programing tip

int-to-Object 비교가 Java 7에서는 유효하지만 Java 8에서는 유효하지 않은 이유는 무엇입니까?

itbloger 2020. 12. 2. 08:12
반응형

int-to-Object 비교가 Java 7에서는 유효하지만 Java 8에서는 유효하지 않은 이유는 무엇입니까?


다음 코드는

private boolean compare(Object a, int b) {
    return a == b;
}

Java 7에서 컴파일되지만 Java 8에서 다음 오류가 발생합니다.

비교할 수없는 유형 : int 및 Object

다음 질문을 살펴보십시오.

Java 7에서 Object와 int 비교

Java 6과 Java 8은 int를 비교할 수 없지만 Object7은 비교할 수 있습니다 . 이것에 대한 문서가 있습니까?

나는 이러한 결정에 영향을 준 배경 지식에 관심이 있습니다. 미정 인 것 같네요.

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 개 가지 언급 ==: 사업자 숫자 , 부울참조 . 없음==우리는 문이 있다는 결론을 내릴 수 있도록 사업자는, 당신의 예에서 일어날 수없는 불법입니다 .

==귀하의 예제에 적용 할 수없는 이유를 살펴 보겠습니다 .

  • 15.21.2. 부울 같음 연산자 == 및! =

    왜 관련이 없는지 언급 할 필요가 없습니다 ..

  • 15.21.3. 참조 같음 연산자 == 및! =

    같음 연산자의 피연산자가 모두 참조 유형이거나 널 유형이면 연산은 객체 같음입니다.

    캐스팅 변환 ( §5.5 ) 을 통해 두 피연산자의 형식을 다른 피연산자의 형식으로 변환 할 수없는 경우 컴파일 타임 오류 입니다. 두 피연산자의 런타임 값은 반드시 같지 않습니다.

  • 15.21.1. 숫자 같음 연산자 == 및! =

    항등 연산자의 피연산자가 모두 숫자 유형이거나 하나가 숫자 유형이고 다른 하나가 숫자 유형으로 변환 가능한 경우 ( §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).

참고URL : https://stackoverflow.com/questions/32632364/why-is-an-int-to-object-comparison-valid-in-java-7-but-not-in-java-8

반응형