[java] 자바 6과 자바 7의 자동 언 박싱 차이점

Java SE 6과 Java SE 7 사이의 자동 언 박싱 동작의 차이에 주목했습니다.이 두 버전간에이 동작의 변경 사항에 대한 문서를 찾을 수 없기 때문에 그 이유가 궁금합니다.

다음은 간단한 예입니다.

Object[] objs = new Object[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];

이것은 Java SE 7의 javac로 잘 컴파일됩니다. 그러나 컴파일러에 “-source 1.6″인수를 지정하면 마지막 줄에 오류가 발생합니다.

inconvertible types
found   : java.lang.Object
required: int

Java SE 6을 다운로드하여 네이티브 버전 6 컴파일러 (-source 옵션없이)로 컴파일하려고했습니다. 위와 동일한 오류에 동의하고 제공합니다.

그래서 무엇을 제공합니까? 더 많은 실험을 통해 Java 6의 unboxing은 (컴파일시) boxed 유형 인 값만 unboxing 할 수있는 것으로 보입니다. 예를 들어, 이것은 두 버전 모두에서 작동합니다.

Integer[] objs = new Integer[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];

따라서 Java 6과 7 사이에서 unboxing 기능이 향상되어 값이 적절한 boxed 유형인지 (컴파일 시간에) 알지 못해도 한 번에 객체 유형을 캐스팅하고 언 박스 할 수 있습니다. 그러나 Java 7이 나왔을 때 작성된 Java Language Specification이나 블로그 게시물을 읽었을 때이 내용의 변경 사항을 볼 수 없으므로 변경 사항이 무엇인지,이 “기능”이 무엇인지 궁금합니다. ?

호기심 일뿐입니다. 변경으로 인해 “잘못된”언 박싱이 발생할 수 있습니다.

Object[] objs = new Float[2];
objs[0] = new Float(5);
int myInt = (int)objs[0];

이것은 잘 컴파일되지만 런타임에 ClassCastException을 제공합니다.

이것에 대한 언급이 있습니까?



답변

Java 7 JLS의 5.5 Casting Conversion 절의 언어가 Java 5/6 JLS의 동일한 절과 비교하여 업데이트 된 것 같습니다. 아마도 허용 된 변환을 명확히하기 위해있을 것입니다.

Java 7 JLS라고

참조 형식의 식은 unboxing 변환에 의해 오류없이 기본 형식으로 캐스팅 변환 될 수 있습니다.

자바 5/6 :

참조 형식의 값은 unboxing 변환 (§5.1.8)을 통해 기본 형식으로 캐스팅 될 수 있습니다.

Java 7 JLS에는 참조 유형에서 기본 형식으로의 허용 된 변환 (이 테이블은 Java 5/6 JLS에 포함되지 않음)의 테이블 (표 5.1)도 포함되어 있습니다. 이것은 Unboxing을 사용한 축소 참조 변환으로 Object에서 primitive 로의 캐스트를 명시 적으로 나열합니다.

이유는 이 이메일에 설명되어 있습니다 .

요점 : 사양. allow (Object) (int) 또한 (int) (Object)를 허용해야합니다.


답변

당신이 옳습니다. 더 간단하게 말하면 :

Object o = new Integer(1234);
int x = (int) o;

이것은 Java 7에서 작동하지만 Java 6 이하에서는 컴파일 오류가 발생합니다. 이상하게도이 기능은 눈에 띄게 문서화되어 있지 않습니다. 예를 들어 여기에 언급되지 않았습니다 . 새로운 기능인지 버그 수정인지 (또는 새로운 버그인지) 논쟁의 여지가 있습니다 . 관련 정보 및 토론을 참조하십시오 . 합의 는 원래 사양 의 모호함 을 지적하는 것으로 보이며 , 이는 JSR 292 (Dynamically Typed Languages)의 구현에 중요했기 때문에 7에서 수정 된 Java 5/6에서 약간 부정확하거나 일관성이없는 구현으로 이어졌습니다.

자바 오토 박싱에는 이제 더 많은 함정과 놀라움이 있습니다. 예를 들면

Object obj = new Integer(1234);
long x = (long)obj;

컴파일되지만 ClassCastException런타임에 실패 합니다. 대신 다음과 같이 작동합니다.

long x = (long)(int)obj;


답변