자바에서 Integer a, b를 같은 값으로 객체 생성하면 각각 새로운 객체를 생성하는 건가요?

조회수 959회

안녕하세요! 자바 책에서 예제를 따라 치다가 궁금해서 질문드립니다.

public static void main(String[] args) {
    Integer o1 = 1000;
    Integer o2 = 1000;
    Integer o3 = new Integer(1000);
    Integer[] arr1 = {1,2};
    Integer[] arr2 = {1,2};
    String s1 = "홍길동";
    String s2 = "홍길동";

}

여기서 o1과 o2는 각각의 객체로 생성되는 건가요? s1과 s2는 같은 객체를 공유하기 때문에 (s1==s2)를 했을 때 true값이 리턴되는데 Integer의 경우, 아래 코드로 비교했을 때 1번이 false가 나와서요.

    //==로 identityHashCode 비교
    System.out.println("Integer o1 == o2: "+(o1==o2));         //------1
    System.out.println("Integer o1 == o3: "+(o1==o3)+"\n");    //------2

    //해쉬코드 비교
    System.out.println("Integr o1, o2, o3.hashCode() 비교");
    System.out.println(o1.hashCode()+", "+o2.hashCode()+", "+o3.hashCode()+"\n");
    System.out.println("Integr o1, o2, o3 IdentityHashCode() 비교");
    System.out.println(System.identityHashCode(o1)+", "+System.identityHashCode(o2)+", "+System.identityHashCode(o3)+"\n");
  • (•́ ✖ •̀)
    알 수 없는 사용자

2 답변

  • 안녕하세요. 잘 알고계시듯이 == 는 값의 메모리 위치 또는 객체 참조를 비교하고 equals 메서드는 값을 비교합니다. 그러나 정수는 -128 에서 +127 까지의 값을 저장하기 위해 내부적으로 캐시를 사용합니다. 따라서 == 연산자는 -128에서 127 사이의 값을 확인하는데 사용되면 true 를 반환합니다. 그러나 그 이상의 값일 경우 새 Integer 객체가 생성되기 때문에 false 를 반환합니다.

    https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

    • (•́ ✖ •̀)
      알 수 없는 사용자
  • ==, equals 차이는 설명을 해주셨으니 String 의 경우를 추가적으로 설명드릴까 합니다.

    자바 1.4 대의 경우로 생각해보죠

    Integer o1 = 1000;    // 에러
    String s1 = "홍길동";    // 정상
    String s2 = "홍길동";    // 정상
    

    자바 1,4로 한정한 이유는 질문자가 혼동을 할 소지가 있기 때문입니다.

    Integer o1 = 1000 코드는 내부적으로 autoboxing 이라는 기능으로 Integer o1 = new Integer(1000) 처럼 실행됩니다.

    그러면 스트링도 위와 같이 String s1 = "홍길동" 이 String s1 = new String("홍길동") 으로 실행되는 것 아닌가 하고 반문 할 수 있는데 그렇지가 않습니다.

    String s1 = new String("홍길동");
    String s2 = new String("홍길동");
    

    상기 두개의 s1, s2 는 서로 다른 것입니다.

    이유를 알려면 JVM 내부의 constants pool 이라는 영역을 알아야 하고 String 의 intern 메소드의 역활도 이해해야 합니다.

    쉽게 답을 적으면 문자열은 상수이고 jvm 에서 상수는 별도 관리를 한다는 것입니다. 그런데 new String 으로 만들게 되면 상수 풀에서 관리하는 것이 아니라 일반 객체와 같이 heap 에 생성을 하게 됩니다.

    즉 문자열이 같게 나오는 이유는 intern 메소드에 의해서 상수풀에 저장되어 있는 "홍길동"("홍길동"은 상수풀에서 1개)을 리턴하기 때문에 같은겁니다.

    • 추가 설명 감사드립니다. 저도 많은 도움이 되었습니다! 알 수 없는 사용자 2018.8.17 20:01
    • 우와 저도 지금 당장은 완벽하게 이해하기는 어려운 것 같지만, 정말 도움이 많이됐습니다! 좀 더 공부하고 다시 한번 설명해주신거 읽으면서 이해하면 좋을 것 같아요!! 정말 감사합니다:) 알 수 없는 사용자 2018.8.18 14:26

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

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

(ಠ_ಠ)
(ಠ‿ಠ)