[java] 자바 : 정수와 ==

자바 1.5로, 당신은 꽤 많이 교류 할 수 Integerint많은 상황에 있습니다.

그러나 코드에서 잠재적 인 결함이 발견되어 조금 놀랐습니다.

다음 코드 :

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 를 확인해야 함 ).


답변

이 큰 대답 외에도 내가 배운 것은 다음과 같습니다.

참조로 객체를 비교하지 않는 한 ==와 객체를 비교하지 마십시오.