JAN's History

자바의 정석 - CH9 lang 패키지 본문

자바

자바의 정석 - CH9 lang 패키지

JANNNNNN 2023. 4. 14. 21:32

1. Object 클래스

: 모든 클래스의 최고 조상. 오직 11개의 메서드만 가지고 있다.

= notify(), wait() 등은 쓰레드와 관련된 메서드이다.

protected => 같은 클래스 내에서만 사용 가능하기 때문에 오버라이딩을 통해 public으로 변경해야 사용할 수 있다.

대부분의 Object 메서드는 오버라이딩 해서 사용한다.

 

1-2 equals(Object obj) 

- 객체 자신(this)와 주어진 객체(obj)를 비교한다. 같으면 true, 다르면 false

- Object클래스의 equals()는 객체의 주소를 비교(참조 변수 값 비교)

=> equals은 String일 때 사용, 아닐 경우엔 ==로 같음을 판단

iv의 주소 값은 v1, v2가 다르기 때문에 false가 나오는 것

iv의 값 (=10)이 같은 지를 판단하기 위해서는 오버라이딩이 필요.

형변환 과정 ( 주소 값이 아닌 value 값으로 비교 하여 v1 = v2가 같다.)

Object 리모콘에는 value가 없다. (단지 최고 조상일 뿐!)

그래서 Object에 value 멤버를 사용할 수 있게 하기 위해서 자손의 멤버를 할당하는 과정 즉, 형변환을 진행해야한다.

Value(자손) v = (Value)obj(조상);를 사용하면 obj를 value로 형변환 시킬 수 있다.

=> 결과적으로 Value에 value라는 소문자 멤버가 있었지만 obj에는 없었기 때문에 obj에도 추가시켜준 것.

+ Value v = Value(); Object o = (Obeject)v로 하면 조상의 멤버를 자손도 사용할 수 있다. (조상 - 자손 관계에선 서로 형변환 가능)

+ 클래스는 참조변수가 필요하니까 꼭 참조변수 선언하는 것

 

instanceof로 형변환 여부를 판단해야함! 

=> 만약 obj가 value의 형변환이 안된다면 false 값을 반환하겠다.

 

equals(Object obj)의 오버라이딩 : 인스턴스 변수(iv)의 값을 비교하도록 보통 equals()을 오버라이딩 한다.

원래는 person p1와 p2가 서로다른 두 객체라서 주소값으로 T/F를 판단하지만 value 값으로 판단하기 위해선 

value 값은 person() 메서드로 정의하고,  obj의 id 값과 person의 id 값(=value값)을 비교하는 것.

형변환을 한번에 할지, 참조변수로 만들고 할지

1-3 hashCode()

: 객체의 해시코드(hash code)를 반환하는 메서드

- object 클래스의 hashCode()는 객체의 주소를 int로 변환해서 반환 (equals처럼)

=> native 메서드 : OS에 작성되어 있는 메서드이기 때문에 바로 선언하여 사용할 수 있다.

둘다 오버라이딩이 잘 되어 있음

=> equals()를 오버라이딩하면 hashCode()도 오버라이딩 해야한다.

     equals()의 결과가 true인 두 객체의 해시코드는 같아야 하기 때문이다.

 

- System.identify.HashCode(Object obj)는 Object클래스의 hashCode()와 동일하다. (참고로만 알아두자)

 : 객체마다 다른 해시코드를 반환할 수 있어 오버라이딩 하기 전 hashCode()를 알고 싶을 때 사용.

1-4 to(~으로)String()

: 객체를 문자열(String)으로 변환하기 위한 메서드

=> iv를 (iv의 집합=객체) 문자열로 바꾼다는 뜻.

기본적으로 Object 클래스의 toString()은 설계도 객체에서 클래스이름의 객체의 주소를 16진수로 바꾸는 것이다.

+@는 위치를 의미.

원래는toString()을 쓰면 Card@(객체주소)를 반환하는 것.

=> 그러나 iv객체를 문자열로 바꿔 반환하고 싶을 땐 오버라이딩을 해줘야함.

toString() 뿐 아니라 equals, hashCode까지 오버라이딩 한 경우 (equals값이 같으면 hashCode 값도 같아야 하기 때문)

+ hashCode는 가변인자라서 ()안에 여러개 변수를 넣어도 된다.

2. String 클래스

: 데이터(char[]) + 메서드(문자열 관련)

- 내용을 변경할 수 없는 불변의 클래스이다.

a = a + b;에서 문자열의 결합인 ab는 a에 들어가면 a는 "a"와의 결합이 끊어지고 새로운 객체가 생성되어 ab를 가리킨다.

=> 즉, 덧셈 연산자를 이용한 문자열의 결합은 성능이 떨어진다.

     문자열의 결합이나 변경이 잦다면, 내용을 변경 가능한 StringBuffer(내용 변경 가능)를 사용해야한다.

 

String str = "abc" vs String str = new String("abc");의 비교

String str1 = "abc"는 abc를 공유할 수 있다. 스트링 문자열은 내용이 변경 불가하기 때문에 공유해도 상관 없다.

String st3 = new String("abc);는 새로운 인스턴스를 생성해 각각의 객체를 만든다.

=> 그러나 굳 new String으로 새로운 인스턴스를 생성할 필요는 거의 없다.

 

문자열 리터럴은 프로그램 실행 시 자동으로 생성된다.

=> 내용을 변경할 수 없으니 여러 참조변수가 공유할 수 있도록 되어있다.

 

2-2 빈 문자열

- 내용이 없는 문자열. 크기가 0인 char형 배열을 저장하는 문자열(C언어에서는 불가하지만 JAVA에서는 허용)

- 크기가 0인 배열을 생성하는 것은 어느 타입이나 가능하다.

 

- 문자(char)와 문자열(String)의 초기화

오른쪽이 더 좋은 코드

=> 초기화는 오른쪽처럼

왼쪽이 더 좋은 코드

왼쪽은 하나의 빈 문자열을 3개의 객체가 공유하지만 오른쪽은 빈 문자열을 각각 만들기 때문에 불필요한 코드가 된다.

 

2-3 String클래스의 생성자와 메서드

1. String(char[] value)  : 주어진 문자를 String 인스턴스를 생성한다.

반대로 String 클래스의 문자열을 문자로 변경하고 싶을 땐 toCharArray()을 사용한다.

2. String(StringBuffer buf) : StringBuffer를 String으로 바꿀 때 사용한다.

StringBuffer = 변경 가능한 문자열

3. char charAt(int index) : 지정된 위치에 있는 문자를 알려준다. (index는 0부터 시작)

4. int compareTo(String str) :  문자열(str)과 사전순서로 비교한다. 사전 순으로 같으면 0, 이전으면 -, 이후면 +를 반환.

int i2="aaa".compareTo("bbb"); => aaa가 bbb보다 작으니까 음수 / int i3="bbb".compareTo("aaa") 오른쪽이 작으면 양수

  => 정렬할 때 사용한다.

5. String concat(String str) : 문자열을 뒤에 덧붙인다.

6. boolean contains(CharSequence s) : 지정된 문자열이 포함되어 있는지 검사한다.

=>CharSequence는 인터페이스다. 인터페이스의 장점은 서로 관계없는 클래스들을 맺어줄 수 있다는 것이다.

    CharBuffer, Segment, String, StringBuffer, StringBuilder가 속해있다. (인터페이스라는 공통점으로 묶어줌)

7. boolean endsWith(String suffix) : 지정된 문자열로 끝나지 검사한다.

8. booelan equals(object obj) : 매개변수로 받은 문자열과(obj) String인스턴스의 문자열을 비교해 같으면 true, 아님 false.

9. boolean equalsIgnoreCase(String str) : 문자열과 String인스턴스의 문자열을 대소문자 구분없이 비교한다.

10. int indexOf(int ch) : 주어진 문자(ch)가 문자열에 존재하는지 확인 후 위치를 알려준다. 없으면 -1을 반환.

...

join() : 여러 문자열 사이에 구분자를 넣어서 결합한다.

string.join("-", arr) => "dog" + "-" +"cat" + "-" +"bear" 이 되는 

2-4 문자열과 기본형 간의 변환

- 숫자를 문자열로 바꾸는 방법 : 숫자 + ""(빈 문자열)을 더하면 된다. / String.valueOf

2가지 방법

=> 1번이 더 편리하고 2번이 더 빠르다.

- 문자열을 숫자로 바꾸는 방법 : Interger.parseInt / Integer.valueOf

2가지 방법

 

3. StringBuffer 클래스 : 문자열을 저장하고 다루는 것.

- String처럼 문자열 배열(char[])을 내부적으로 가지고 있다.

- 그러나 String은 불변(변경 불가)이고 StringBuffer은 가변(변경 가능)하다.

 

=> 문자열을 다룰 땐 기본적으로 String클래스를 쓰지만 다루거나 조작할 때는 StringBuffer을 사용함.

- 배열은 길이 변경 불가. 공간이 부족하면 새로운 배열을 생성해야한다.

1. 새로운 배열을 만든다.

2. 공간부의 내용을 복사한다.

3. 참조를 변경한다.

- StringBuffer은 저장할 문자열의 길이를 고려하여 적절한 크기로 생성해야한다.

- StringBuffer은 String과 달리 내용변경이 가능하다.

  > append() : 끝에 문자열 추가

  > delete() : 삭제

  > insert() : 삽입

- append()는 지정된 내용을 StringBuffer에 추가 후, StringBuffer의 참조를 반환한다.

sb뒤에 ZZ를 추가한 것을 sb2에 담아 "abc123ZZ"가 저장된다고 하면 sb에도 "abc123ZZ"가 저장된다.

그래서 이를 합쳐 sb.append("123").append("ZZ");가 될 수 있다.

- StringBuffer은 String과 달리 equals()가 오버라이딩 되어 있지 않아 주소를 비교한다. 

=> this == obj라는 뜻

= > StringBuffer을 String으로 변환 후에 equals()로 비교해야 한다.

3-2 StringBuffer의 생성자와 메서드

StringBuffer 예제

=> 눈으로 이해해보기

 

3-3 StringBuilder (동기화X, 싱글스레드 프로그)

- StringBuffer는 동기화되어 있다. 멀티 스레드에 안전하다.(thread-safe)

싱글 스레드 : 한번에 1개의 작업을 하는 것

멀티 스레드 : 한번에 N개의 작업을 하는 것(Ex) 파일 다운로드 하며 채팅할 수 있는 동시진행할 수 있는 것)

- 멀티 스레드 프로그램이 아닌 경우, 동기화는 불필요한 성능 저하이다.

=> 이럴 떈 StringBuffer 대신 StringBuilder를 사용하면 성능이 향상된다.

=> 클래스 이름만 바꾸면 된다. 안에 사용되는 메서드는 전부동일

+ 지금까지 작성한 프로그램은 전부 싱글 스레드이고, 멀티 스레드로 프로그램을 작성하는 방법은 13장 스레드에서 배움.

4 Math 클래스

- 수학관련 static메서드의 집합(참조변수 필요X)

- round()로 원하는 소수점 아래 세 번째 자리에서 반올림하기

=> 소수점 이하의 결과값을 얻고 싶다면 실수로 (double)로 나눠야한다.

rint vs round

=> rint()는 소수점이 .5일 때 짝수 번호로 내림을 하고 round()는 .5일 때 무조건 올림을 한다.

round() vs rint()

=> round()는 항상 .5일때 올림을 하고 rint()는 홀수일떈 올리고 짝수일 떈 내리기 때문에 sum 값이 평균적으로 더 정확.

 

4-2 wrapper(래퍼)클래스

- 8개의 기본형을 객체로 다뤄야할 때 사용하는 클래스

=> 기본형을 감싸는 클래스

기본형 - 래퍼 클래스

=>Interger는 기본적으로 int를 가지고 있지만 최대값 최소값도 가지고 있다.

4-3 Number 클래스

: 모든 숫자 래퍼 클래스의 조상

조상 Number
Number Class의 내부

=>래퍼 객체가 가지고 있는 값을 기본형으로 반환해준다.

 

4-4 문자열을 숫자로 변환하기

 >Integer -> int로 변경하기 위해선 intValue()를 사용

 >Integer.parseInt 사용

 >Integer.valueOf 사용.

문자열->기본형  문자열 -> 래퍼클래스

- n진법의 문자열을 숫자로 변환하는 방법

=> 기본적으로는 10진법이지만 다른 진수로 바꾸고 싶을 땐 따로 적어주면 됨

4-5 오토박싱 & 언박싱

:기본형과 참조형간의 자동 형변환

=> 오토박싱, 언박싱 모두 자동으로 바꿔줌

기본형의 값을 객체로 자동변환하는 것을 오토박싱, 그 반대는 언박싱.