자바 .hashcode() 질문드립니다!
조회수 1566회
자바에서 실제 데이터가 저장되있는 메모리 주소를 보고싶습니다. C에서 &를 써서 보는것 처럼요. 찾아보니 .hashcode()가 있더라구요. hashcode에관한 질문좀 드립니다.
만약에 이러한 코드가 있다면,
public static void main(String[] args){
Car k = new Car();
Car a = new Car();
System.out.println(a); // Car.Car@15db9742
System.out.println(k); // Car.Car@6d06d69c
}
public static void main(String[] args){
Car k = new Car();
Car a = new Car();
System.out.println(a); // Car.Car@15db9742
}
public static void main(String[] args){
Car k = new Car();
Car a = new Car();
System.out.println(k); // Car.Car@15db9742
}
주석 처리된 값이 나옵니다.
1> new로 서로다른 객체를 만들어 줬지만, 왜 k,a는 같은 hashcode값을 가지는 건가요? 가비지컬렉터때문에 사용되지 않는 객체를 처리해줘서 같은 건가요?
2> hashcode는 힙에 있는 주소를 가리키는 건가요? 대게 new를 이용하여 만든 객체들이 힙공간에 저장되어 사용된다고 들었습니다. 그럼 hashcode는 힙공간에서 객체가 위치하는 메모리값을 반환하는 건가요?
3> Integer 를 사용하여 int를 객체화 시켜서 hashcode를 해보면, 입력한 숫자 그대로를 출력하는 걸 볼 수 있는데 왜 그런가요? 저는 Integer로 선언된 변수의 주소를 보고 싶습니다. 방법이 없나요?
2 답변
-
1) HashMap과 같은 클래스들을 개체들을 구별하기 위해서 hash값을 사용합니다. hash는 개체를 판별하기 위한 값 정도로 보시면 됩니다. hash값이 같다고 같은 개체는 아닙니다. 예를 들어 숫자값 30, 35, 40 이라는 데이타가 있고 hash 공식을 n%10으로 두면 30은 0, 35는 5, 40은 0의 hash값을 가지게 됩니다. 30, 40은 같은 hash값을 가지는 것이죠. 물론 다른 데이타 입니다. hash값은 map등의 클래스에서 개체의 검색 속도를 높일때 사용됩니다. 개체 비교시에도 hash가 틀리면 전체값을 비교하지 않고 바로 틀리다고 판단하므로 속도 향상에 도움이 됩니다.
2) hashcode는 주소값이 아닙니다. java에서 직접 heap 주소를 볼 수 있는 방법은 없습니다. JVM 내부적으로 메모리가 관리되므로 개체가 항상 똑같은 주소를 가지고 있지도 않습니다.
3) 그건 hashcode를 만드는 알고리즘이 그렇기 때문입니다. 일반적으로 사용자가 만드는 개체의 경우 자신만의 hash 알고리즘을 만들수 있습니다.
마지막으로 주소값이 궁금한 이유가 알고싶긴 하네요. Java의 경우 개발자가 gc에 관여할 수 없습니다.(gc 정책을 변경할수는 있습니다). C와는 전혀 다른 언어라고 생각하시는게 마음이 편하실 듯 하네요. 자바의 메모리 관리에 대한 자료를 알고 싶으시면 gc 관련한 글들을 읽어 보시면 됩니다. 왜 메모리 값을 알 수 없는지도 아실 수 있을 듯 합니다.
-
(•́ ✖ •̀)
알 수 없는 사용자
-
-
1.
클래스(타입)는 같더라도 해당 클래스를 기반으로 만들어진 인스턴스는 각각 개별로써 취급됩니다. 개체라고 하죠.
System.out.println()
메서드는 인자가 객체 타입일 때 해당 객체가 소유한toString()
메서드가 반환한 문자를 출력합니다.직접 만드신
Car
클래스는toString()
메서드가 오버라이드 되어 있지 않으므로 Object 클래스의toString()
메서드가 호출될 것이며Object.toString()
은Object.hashCode()
를 호출해서 인스턴스의 해시값을 출력하도록 작성되어 있습니다.해시값은 인스턴스의 고유값, ID 정도로 생각하시면 됩니다.
2.
메모리는 잘 몲...
3.
System.out.println()
은 인자의toString()
메서드를 호출합니다.Integer.toString()
은Object.toString()
과 다르게 인스턴스가 갖고 있는 int 값을 반환하도록 작성되어 있습니다.
댓글 입력