자바 1.5로, 당신은 꽤 많이 교류 할 수 Integer
와 int
많은 상황에 있습니다.
그러나 코드에서 잠재적 인 결함이 발견되어 조금 놀랐습니다.
다음 코드 :
Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
mismatch = true;
어떤 상황에서 결정할 수는 없지만 값이 같을 때 불일치가 잘못 설정 된 것처럼 보입니다. Eclipse에서 중단 점을 설정하고 Integer
값이 모두 137 임을 보았고 부울 표현식을 검사하여 그것이 거짓이라고 말했지만 단계를 넘어 서면 불일치를 true로 설정했습니다.
조건부 변경 :
if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))
문제를 해결했습니다.
왜 이런 일이 일어 났는지 누군가가 밝힐 수 있습니까? 지금까지 내 PC의 로컬 호스트에서만 동작을 보았습니다. 이 특정한 경우에, 코드는 약 20 번의 비교를 성공적으로 통과했지만 2에서 실패했습니다. 문제는 일관되게 재현 가능합니다.
널리 퍼져있는 문제라면 다른 환경 (dev 및 test)에서 오류가 발생했을 것입니다. 그러나 지금까지이 코드 스 니펫을 실행하는 수백 번의 테스트 후에 아무도 문제를보고하지 않았습니다.
==
두 Integer
값 을 비교 하는 데 여전히 합법적이지 않습니까?
아래의 모든 훌륭한 답변 외에도 다음 스택 오버플로 링크에는 약간의 추가 정보가 있습니다. 실제로 내 원래의 질문에 대답했지만 내 질문에 오토 박스를 언급하지 않았기 때문에 선택한 제안에 표시되지 않았습니다.
컴파일러 / JVM이 오토 박싱을“그냥 작동”할 수없는 이유는 무엇입니까?
답변
JVM이 정수 값을 캐싱 중입니다. ==는 -128에서 127 사이의 숫자에서만 작동합니다.
http://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching
답변
당신은 Integer
간단한 두 가지 를 비교할 수 없습니다==
객체를 객체 없으므로 대부분의 시간 참조는 동일하지 않습니다.
Integer
-128과 127 사이 의 트릭 이 있습니다. 참조는 Integer.valueOf()
작은 정수를 캐시하는 자동 상자 사용과 동일 합니다.
박스형 값 p가 true, false, 바이트, \ u0000 ~ \ u007f 범위의 문자 또는 -128과 127 사이의 정수 또는 짧은 숫자 인 경우 r1과 r2를 두 개의 권투 변환의 결과로 둡니다. p. 항상 r1 == r2입니다.
자료 :
같은 주제에서 :
답변
문제는 두 정수 객체가 바로 그 객체라는 것입니다. 값이 아닌 두 개의 객체 참조를 비교하기 때문에 일치하지 않습니다. .equals
객체 참조 비교와 반대로 값 비교를 제공하기 위해 분명히 재정의됩니다.
답변
Integer
참조를 참조합니다. 즉, 참조를 비교할 때 값이 아닌 동일한 객체를 가리키는 경우 비교합니다. 따라서 현재보고있는 문제입니다. 일반 int
유형 과 잘 작동하는 이유 는에 포함 된 값을 개봉하기 때문 Integer
입니다.
당신이하고있는 일을하고 있다면 왜 if
진술을 시작 해야한다고 덧붙이 겠습니까?
mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) );
답변
“==”는 항상 메모리 위치 또는 값의 객체 참조를 비교합니다. equals 메소드는 항상 값을 비교합니다. 그러나 equals는 간접적으로 “==”연산자를 사용하여 값을 비교합니다.
정수는 정수 캐시를 사용하여 -128에서 +127 사이의 값을 저장합니다. == 연산자를 사용하여 -128에서 127 사이의 값을 확인하면 true를 반환합니다. 이러한 값 이외의 경우 false를 반환합니다.
추가 정보 는 링크 를 참조하십시오
답변
사용의 정확성을 위해 다음과 같이 비교 하기 전에 ==
비교 된 Integer
값 중 하나를 개봉하면 됩니다 ==
.
if ( firstInteger.intValue() == secondInteger ) {..
두 번째는 자동으로 개봉됩니다 (물론 null
먼저 s 를 확인해야 함 ).
답변
이 큰 대답 외에도 내가 배운 것은 다음과 같습니다.
참조로 객체를 비교하지 않는 한 ==와 객체를 비교하지 마십시오.