메모리 관점에서 본 String
package p20140124; class StringEx1 { public static void distinction(boolean value){ if(value){ System.out.println("true"); }else{ System.out.println("false"); } } public static void main(String[] args) { String str1 = "marvell"; String str2 = new String("marvell"); if (str1 == str2) { distinction(true); } else { distinction(false); } if (str1.equals(str2)) { distinction(true); } else { distinction(false); } if(str1.hashCode()==str2.hashCode()){ distinction(true); }else{ distinction(false); } if(System.identityHashCode(str1)==System.identityHashCode(str2)){ distinction(true); }else{ distinction(false); } } } /* output false true true false */
/* http://cafe.naver.com/javachobostudy/57390 차가운잎사귀(Idshyun2)님의 글에서 가져온 내용임을 밝힙니다. */
str1 - 리터럴 영역의 메모리 주소를 직접접근
str2 - 힙영역의 메모리 주소를 통해 간접접근
힙영역은 단지 리터럴 영역의 메모리주소 값을 보관하기 위한 메모리 영역에 지나지 않습니다.
- 큰 따옴표를 이용해 문자를 대입하면, 바로 Constant pool, 즉 상수 메모리 영역에 저장이 된다. 이 메모리는 누군가가 한명이라도 참조하고 있는한 사라지지 않는다.
- 반면 힙을 통해서 만든 String 객체는 일단 힙 메모리 주소를 가리키기 때문에 == 연산자를 통해 str1과 str2를 단순 비교 하면 다른 객체라고 뜬다.
/* http://cafe.naver.com/javachobostudy/57390 남궁성님 리플에서 가져온 내용임을 밝힙니다. */
- HashCode()는 모든 클래스의 조상인 Object에 정의되어 있는 메서드인데, 이는 주소값을 이용하여 해쉬코드(int 정수형)을 만든다. 때문에 이론상으로 HashCode()를 이용하여 객체를 구분할 수가 있다.
그런데 String 클래스는 Object 클래스로부터 상속받은 HashCode()를 오버라이딩해서 그 내용을 바꿔버린다. 즉, 주소값을 가지고 해쉬코드를 만드는게 아니라 문자열의 내용으로 해서 코드를 만든다. 따라서 해쉬코드가 동일했던 것이다.
한편 identityHashCode는 객체의 주소값을 가지고 HashCode를 생성하는 메서드이고, 이는 String과 같이 HashCode()를 오버라이딩한 경우에도 다른 객체는 다른 HashCode를 얻게 된다.
'Java' 카테고리의 다른 글
[Java] list와 향상된 for문 (2) | 2014.02.09 |
---|---|
[Java] 2차원 배열의 길이 (0) | 2014.02.08 |
[Java] String과 StringBuffer의 차이점 (0) | 2014.01.24 |
[Java] 상수(Constant) (0) | 2014.01.24 |
[Java] String constant pool (0) | 2014.01.24 |