객체의 해시코드(hash code)를 반환하는 메서드
- 해시코드 = 정수값 ("해시"라는 알고리즘에서 사용)
Object클래스의 hashCode()는 객체의 주소를 int로 변환해서 반환public class Object { ... public native int hashCode(); // 네이티브메서드 : OS의 메서드(C언어로 작성되어 있다.) & 이미 작성된 것을 사용하기 때문에 내용이 없다. }
- 객체의 주소로 반환하기 때문에 객체마다 다른 값을 가진다.(= 객체의 지문)
equals()를 오버라이딩하면, hashCode()도 오버라이딩해야 한다.- equals()와 hashCode()는 둘 다 주소를 가지고 작업을 한다.
- equals()가 iv를 통해 작업을 한다면, hashCode()도 iv를 통해 작업을 해야 한다.
- equals()의 결과가 true인 두 객체의 해시코드는 같아야 하기 때문
- 주소를 가지고 있지만, iv를 통해 오버라이딩 한다.
- 위의 String은 오버라이딩이 잘 되어 있는 경우다.
System.idnetityHashCode(Object obj)는 Object클래스의 hashCode()와 동일
- idnetityHashCode = 객체마다 다른 해시코드를 반환한다.
- 32bit JVM은 주소가 int타입 / 64bit JVM은 주소가 8byte(long) 그래서, 64bit JVM으로 HashCode()를 만들게 되면, 겹치는 값이 생성될 수 있다.
toString() : 객체를 문자열(String)으로 변환하기 위한 메서드
public String toString() { // Object클래스의 toString() return getClass().getName()"@"+Integer.toHexString(hashCode()); // 설계도객체 클래스이름 at(위치) 해시코드(객체주소)를 16진수로 표현 }
- 클래스이름 + 주소값이 나오게 된다.
- 그런데, Object에 있는 toString()은 유용하지 못하므로 iv의 값을 출력하도록 오버라이딩 해준다.
- 결과가 변하게 된다.
- 객체==iv집합이므로 객체를 문자열로 변환한다는 것은 iv의 값을 문자열로 변환한다는 것과 같다.
- 그렇기 때문에, 오버라이딩 한다는 것은 iv를 문자열로 바꾸는 의미이므로 오버라이딩을 할 때 iv를 활용한다.
String 클랫 = 데이터(char[]) + 메서드(문자열 관련)
- 데이터 = 문자배열
- 메서드 = 문자열을 다루는데 필요한 메서드
public final class String implements java.io.Serializable, Comparable { private char[] value; ...
내용을 변경할 수 없는 불변(immutable)클래스
String a = "a"; String b = "b"; a = a + b;
- a와 b가 더해져서 기존 주소값에 저장되는 것이 아니라, 새로운 주소값에 저장이 된다.
(내용을 변경할 수 없으므로)- 0x300이 기존의 a의 값에 저장된다.
덧셈 연산자(+)를 이용한 문장려 결합은 성능이 떨어짐. 문자열의 결합이나 변경이 잦다면, 내용을 변경가능한 StringBuffer를 사용(StringBuffer는 내용 변경 가능)
String str = "abc"와 String str = new String("abc");의 비교
- 첫 번째 = 문자열 리터럴
- 두 번째 = new 연산자
- str1과 str2는 "abc"를 가리키고 str3과 str4는 각각의 "abc"를 가리킨다.
- 즉, 문자열 리터럴로 문자열을 만들면, 하나의 문자열을 여러 참조변수가 공유한다.
- new 연산자를 사용하면, 항상 새로운 객체(문자열)가 만들어진다.
- 문자열은 내용 변경 불가. (여러 참조 변수가 공유해도 문제X) 그래서 굳이 new 연산자 사용할 필요 X
- 그래서 str1과 str2의 참조변수 값을 비교하면 같은 값이 된다.
- str3과 str4는 서로 다른 객체이므로 다른 값이 된다.
- 그래서 문자열을 비교할 때는 == 대신 equals()를 사용해야 한다.
- equals는 내용비교, ==은 주소비교(어떨 때는 true, 어떨 때는 false)
문자열 리터럴은 프로그램 실행시 자동으로 생성된다.(constant pool에 저장)
- contant pool = 상수 저장소
같은 내용의 문자열 리터럴은 하나만 만들어진다.
- 문자열 리터럴도 String 객체다. (내용변경이 불가하다.)
내용이 없는 문자열. 크기가 0인 char형 배열을 저장하는 문자열
String str = ""; // str을 빈 문자열로 초기화
크기가 0인 배열을 생성하는 것은 어느 타입이나 가능
char[] chArr = new char[0]; // 길이가 0인 char 배열 int[] iArr = {}; // 길이가 0인 int 배열
- 숫자를 문자로 바꿀 때 사용
- 배열을 초기화 할 때 null보다 빈 문자열이 유리하다.
문자(char)와 문자열(String)의 초기화
- null 혹은 유니코드의 첫번째 문자인 기본값을 사용하지 않고 공백 또는 빈 문자열로 초기화한다.
String str1 = ""; String str4 = new String(""); String str2 = ""; String str5 = new String(""); String str3 = ""; String str6 = new String("");
- str1~3이 str4~6 보다 더 잘 써진 코드이다.
- str4~6은 new 연산자를 사용했기 때문에 계속 빈 배열이 생성된다.