[JAVA] 자바에서 객체 불변성을 확인하기 위한 .hashCode(), System.identityHashCode() 값 비교

객체의 불변성을 확인해보기 위해서 원시 타입과 참조 타입을 자바와 OS에서 해쉬값을 확인해보았다.



============================= Java =============================

package practice;


import java.util.ArrayList;

import java.util.List;


public class practice {


public static void main(String[] args) {

System.out.println("1. primitive type");

// 객체의 불변성 확인

// 1. primitive type

int integerA = 3;

int integerB = 3;

// .hashCode()가 없어서 에러가 난다.

//System.out.println(integerA.hashCode());

System.out.println("System.identityHashCode(integerA) : "+System.identityHashCode(integerA));

System.out.println("System.identityHashCode(integerB) : "+System.identityHashCode(integerB));

System.out.printf("System.identityHashCode(integerA) == System.identityHashCode(integerB) : %s \n", System.identityHashCode(integerA)==System.identityHashCode(integerB));

// .equals()도 동작하지 않는다.

//System.out.println(System.identityHashCode(integerA).equals(System.identityHashCode(integerB)));

//공백

System.out.println();

System.out.println();

System.out.println();

System.out.println("2. reference type");

System.out.println("2.1 String의 경우");

// 2. reference type

// 2.1 String의 경우

String stringA = "dangal";

String stringB = "dangal";

System.out.printf("stringA == stringB : %s \n",stringA == stringB);

System.out.printf("stringA.equals(stringB) : %s\n",stringA.equals(stringB));

// 2.1.1 .hashCode()의 경우

System.out.println("stringA.hashCode() : "+stringA.hashCode());

System.out.println("stringB.hashCode() : "+stringB.hashCode());

System.out.printf("stringA.hashCode() == stringB.hashCode() : %s \n", stringA.hashCode()==stringB.hashCode());

// 2.1.2 .identityHashCode()의 경우

System.out.println("System.identityHashCode(stringA) : "+System.identityHashCode(stringA));

System.out.println("System.identityHashCode(stringB) : "+System.identityHashCode(stringB));

System.out.printf("stringA.hashCode() == stringB.hashCode() : %s \n", System.identityHashCode(stringA)==System.identityHashCode(stringB));

// 공백

System.out.println();

System.out.println("2.2 List의 경우");

// 2.2 List의 경우

List<Object> listA = new ArrayList<>(); // [1,2,3] 를 넣을 예정

List<Object> listB = new ArrayList<>(); // [1,2,3] 를 넣을 예정

List<Object> listC = new ArrayList<>(); // 중간에 순서를 바꿔 [1,3,2] 를 넣을 예정

// 데이터 입력

for(int i = 1 ; i < 4 ; i++) {

listA.add(i);

listB.add(i);

}

listC.add(1);

listC.add(3);

listC.add(2);

System.out.printf("listA == listB : %s \n",listA == listB);

System.out.printf("listA.equals(listB) : %s \n",listA.equals(listB));

System.out.printf("listA == listC : %s \n",listA == listC);

System.out.printf("listA.equals(listC) : %s \n",listA.equals(listC));

// 2.2.1 .hashCode()의 경우

System.out.println("listA.hashCode() : "+listA.hashCode());

System.out.println("listB.hashCode() : "+listB.hashCode());

System.out.println("listC.hashCode() : "+listC.hashCode());

System.out.printf("listA.hashCode()==listB.hashCode() : %s \n", listA.hashCode()==listB.hashCode());

System.out.printf("listA.hashCode()==listC.hashCode() : %s \n", listA.hashCode()==listC.hashCode());

// 2.2.2 .identityHashCode()의 경우

System.out.println("System.identityHashCode(listA) : "+System.identityHashCode(listA));

System.out.println("System.identityHashCode(listB) : "+System.identityHashCode(listB));

System.out.println("System.identityHashCode(listC) : "+System.identityHashCode(listC));

System.out.printf("System.identityHashCode(listA)==System.identityHashCode(listB) : %s \n", System.identityHashCode(listA)==System.identityHashCode(listB));

System.out.printf("System.identityHashCode(listA)==System.identityHashCode(listC) : %s \n", System.identityHashCode(listA)==System.identityHashCode(listC));

}// end of main()

}// end of class practice{}


============================= Java =============================



================================= 출력 =================================

1. primitive type

System.identityHashCode(integerA) : 118352462

System.identityHashCode(integerB) : 118352462

System.identityHashCode(integerA) == System.identityHashCode(integerB) : true 




2. reference type

2.1 String의 경우

stringA == stringB : true 

stringA.equals(stringB) : true

stringA.hashCode() : -1339091551

stringB.hashCode() : -1339091551

stringA.hashCode() == stringB.hashCode() : true 

System.identityHashCode(stringA) : 356573597

System.identityHashCode(stringB) : 356573597

stringA.hashCode() == stringB.hashCode() : true 


2.2 List의 경우

listA == listB : false 

listA.equals(listB) : true 

listA == listC : false 

listA.equals(listC) : false 

listA.hashCode() : 30817

listB.hashCode() : 30817

listC.hashCode() : 30847

listA.hashCode()==listB.hashCode() : true 

listA.hashCode()==listC.hashCode() : false 

System.identityHashCode(listA) : 1735600054

System.identityHashCode(listB) : 21685669

System.identityHashCode(listC) : 2133927002

System.identityHashCode(listA)==System.identityHashCode(listB) : false 

System.identityHashCode(listA)==System.identityHashCode(listC) : false 


================================= 출력 =================================


결과를 해석 해보자.

1. 원시타입의 경우 .hashCode() 메서드가 없다. Java에 기본 할당 공간이 따로 있다는 것이다.
2. 원시타입의 .identityHashCode()는 동일하게 나왔다. OS에서도 동일한 값으로 처리가 된다.
3. 참조타입 중 String은 A,B 둘 다 .hashCode(), .identityHashCode()가 같게 나왔다.
4. 참조타입 중 List는 데이터가 들어간 순서가 다르면 Java에서 다른 .hashCode()값이 나온다.
5. 참조타입 중 List는 동일한 데이터가 들어간 경우 Java에서는 같았지만 OS에서는 달랐다. 
     이유는 List는 불변객체가 아닌 가변객체이기 때문이다.


+ Recent posts