자바 .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

    싫어요
    채택 취소하기

    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 관련한 글들을 읽어 보시면 됩니다. 왜 메모리 값을 알 수 없는지도 아실 수 있을 듯 합니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 진짜 많은 도움되었어요. 찾아보고 공부하게 되었네요 감사합니다. 심승현 2018.8.31 19:32
  • 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 값을 반환하도록 작성되어 있습니다.

    • 댓글 감사합니다. 1번답에서 하나만 더 질문 할께요. '인스턴스의 해시값을 력하도로 작성' 이라고 설명해주셨는데 new를 하는 순간 인스턴스는 만들어지게 되는거 아닌가요? 그렇게 된다면 2,3번 소스코드에서 해쉬코드값이 다르게 나와야 되는거 아닌가요? 그리고.. 실제주소를 볼 순 없나요? 심승현 2018.8.29 13:46

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)