JAVA 에는 primitive type 과 reference type이 있다.
primitivte type는 값 자체를 가지고 있는 변수고, (int float, ....)
reference type는 값을 저장하는 주소를 가지고 있다. (Class , Collections 등등)
그러므로 C나 C++ pointer를 이용해서 call by reference를 적용시켰지만, java에서는 reference 자체를 넘기면 call by reference을 적용시킬수 있다.
그러므로 reference type에서 ==는 클래스에 저장된 값을 비교하는 것이 아니라 클래스의 메모리 주소를 비교하는 것이다.
그러므로 int 의 wrapper class인 Integer에 같은 값을 저장한후 == 을 하면 당연히 false가 나타나야한다.
하지만 아래의 결괄르 보면
47의 경우 ==가 true가 나오고
3333의 경우는 ==가 false가 나온다는 것을 알수 있다.
이 이유는 JAVA에서 -128 ~ 127 범위의 정수 객체를 캐싱해놓기 때문이다.(이 값들은 빈번하게 사용되기 때문에)
/** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} instance is not * required, this method should generally be used in preference to * the constructor {@link #Integer(int)}, as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. *
캐시는 static block에 의해 IntegerCache 클래스가 메모리에 로드되는 처음에 초기화된다.
이 캐시의 범위는 JVM 옵션을 통해 다음과 같이 조정할 수 있다 . (-XX:AutoBoxCacheMax)
Integer 뿐만 아니라 Long Characater 등 모든 Wrapper clasas에 해당되는 사항이다.
그러므로 JAVA에서 reference type의 값을 비교할때는 == 이 아니라 반드시 equals 함수를 오버라이딩 한후에 equals 함수를 사용하자.
'JAVA' 카테고리의 다른 글
JAVA 8 - 람다 추가 (0) | 2020.08.15 |
---|---|
JAVA 8 (2) - Optional (0) | 2020.08.15 |
웹서버 vs WAS (0) | 2020.08.07 |
StringBuilder vs StringBuffer (0) | 2020.07.02 |
Java String (0) | 2020.07.02 |