int-to-Object 비교가 Java 7에서는 유효하지만 Java 8에서는 유효하지 않은 이유는 무엇입니까?
다음 코드는
private boolean compare(Object a, int b) {
return a == b;
}
Java 7에서 컴파일되지만 Java 8에서 다음 오류가 발생합니다.
비교할 수없는 유형 : int 및 Object
다음 질문을 살펴보십시오.
Java 6과 Java 8은 int
과 를 비교할 수 없지만 Object
7은 비교할 수 있습니다 . 이것에 대한 문서가 있습니까?
나는 이러한 결정에 영향을 준 배경 지식에 관심이 있습니다. 미정 인 것 같네요.
JDK 1.7.0.51과 함께 IntelliJ IDEA 14.1.4를 사용하고 있습니다.
Java 7은 int에 오토 박싱을 적용합니다.
private boolean compare(java.lang.Object, int);
Code:
0: aload_1
1: iload_2
2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: if_acmpne 12
8: iconst_1
9: goto 13
12: iconst_0
13: ireturn
나는 이것을 build 1.7.0_71-b14
편집하다:
이 동작은 Oracle에서 버그로 인식되고 처리되었습니다.
JDK-8013357 : Javac가 잘못된 이진 비교 작업을 허용합니다.
관련 JLS 섹션은 15.21입니다. Javac는 이것을 참조 비교로 취급하는 것처럼 보이지만 참조 비교는 두 피연산자가 참조 유형 인 경우에만 허용됩니다.
...
JLS 섹션 15.21의 이진 비교에 대한 유형 규칙은 이제 javac에 의해 올바르게 적용됩니다. JDK5 이후 javac는 JLS 15.21에 따라 잘못 입력 된 Object-primitive 비교가있는 일부 프로그램을 허용했습니다. 이러한 비교는 이제 유형 오류로 올바르게 식별됩니다.
- JLS 제 15 장 평등 운영자는 3 개 가지 언급 ==
: 사업자 숫자 , 부울 및 참조 . 없음 의 ==
우리는 문이 있다는 결론을 내릴 수 있도록 사업자는, 당신의 예에서 일어날 수없는 불법입니다 .
==
귀하의 예제에 적용 할 수없는 이유를 살펴 보겠습니다 .
-
왜 관련이 없는지 언급 할 필요가 없습니다 ..
-
같음 연산자의 피연산자가 모두 참조 유형이거나 널 유형이면 연산은 객체 같음입니다.
캐스팅 변환 ( §5.5 ) 을 통해 두 피연산자의 형식을 다른 피연산자의 형식으로 변환 할 수없는 경우 컴파일 타임 오류 입니다. 두 피연산자의 런타임 값은 반드시 같지 않습니다.
-
항등 연산자의 피연산자가 모두 숫자 유형이거나 하나가 숫자 유형이고 다른 하나가 숫자 유형으로 변환 가능한 경우 ( §5.1.8 ) 피연산자에 대해 이진 숫자 승격이 수행됩니다 ( §5.6.2 ).
이제 합법적이고 컴파일러가 줄을 다음과 같이 변경했다고 가정 해 봅시다.
if (a == new Integer(b))
결과가 어떻게 될 것으로 예상하십니까? 조건은로 평가되지 true
않으므로 Java 8에서 수정 된 버그 라는 것이 합리적입니다 .
javac 1.7.0_75 또는 javac 1.8.0_60으로 컴파일 (bool → boolean 수정) 예제를 얻을 수 없습니다. 나는 JDK6가 없지만 거기에서도 작동해야한다고 생각하지 않습니다. 아마도 Axel 힌트처럼 이전의 ecj 비 호환성이거나 javac의 다른 부 버전의 버그 일 수 있습니다.
어쨌든 작동한다면 오토 박싱 때문입니다. 스트림과 오토 박싱이 너무 잘 섞이지 않기 때문에 Java 8을 준비 할 때이 문제가 축소되었을 수 있습니다.
JLS 7 에 따르면 컴파일되지 않아야합니다 . int
박스형 숫자 유형, 즉 Byte, Short, Character, Integer, Long, Float, Double과 비교할 수 있습니다. 하지만 그게 다입니다.
And if comparison is between int
and say Float
, Float
will be unboxed first, so that the comparison is between float
and int
. It'll make no sense to do the other way around - box int
then examine the identity of the Integer
(with a Float
no less).
'programing tip' 카테고리의 다른 글
Visual Studio를 사용하는 GCC? (0) | 2020.12.02 |
---|---|
기본적으로 display : inline-block? (0) | 2020.12.02 |
Android SDK Manager의 Google 웹 드라이버는 무엇입니까? (0) | 2020.12.02 |
패키지 종속성을 자동으로 설치하도록 CRAN에 지시하는 방법은 무엇입니까? (0) | 2020.12.02 |
dcast와 유사한 깔끔한 여러 열에 스프레드를 사용할 수 있습니까? (0) | 2020.12.02 |