IDE를 사용하여 일부 퀴즈 에서이 코드 스 니펫을 가져 와서 결과를 길고 길게 얻었지만 정답은 Byte, Byte입니다 . 왜 다른 결과를 얻었습니까? 이 질문은 JDK 11과 관련이 있습니다
public class Client {
static void doCalc(byte... a) {
System.out.print("byte...");
}
static void doCalc(long a, long b) {
System.out.print("long, long");
}
static void doCalc(Byte s1, Byte s2) {
System.out.print("Byte, Byte");
}
public static void main(String[] args) {
byte b = 5;
doCalc(b, b);
}
}
편집 :
코드는 여기에 있습니다 : Oracle 인증 개요 및 샘플 질문
(페이지 : 13, 질문 : 5)
답변
따라서 컴파일 타임에 메소드 서명을 결정하기 위해 Java 언어 사양 을 살펴보면 분명합니다.
첫 번째 단계 (§15.12.2.2)는 복싱 또는 언 박싱 변환을 허용하거나 가변 arity 메소드 호출을 사용하지 않고 과부하 해결을 수행합니다. 이 단계에서 적용 가능한 방법을 찾지 못하면 처리는 두 번째 단계로 계속 진행됩니다.
두 번째 단계 (§15.12.2.3)는 복싱 및 언 박싱을 허용하면서 과부하 해결을 수행하지만 가변 arity 메소드 호출의 사용은 여전히 금지합니다. 이 단계에서 적용 가능한 방법을 찾지 못하면 처리는 세 번째 단계로 계속 진행됩니다.
세 번째 단계 (§15.12.2.4)에서는 과부하를 다양한 arity 방법, boxing 및 unboxing과 결합 할 수 있습니다.
따라서 위의 단계에서 첫 번째 단계에서 Java 컴파일러는 다음과 같은 일치하는 메소드를 찾을 것 doCalc(long a,long b)
입니다. 당신의 방법 doCalc(Byte s1, Byte s2)
은 호출하는 동안 자동 박스가 필요하므로 덜 선호됩니다.
답변
귀하의 경우에 일어나는 일은 런타임 동안 JVM이 확장 변환 을 수행하기로 선택 byte -> long
한다는 것 RuntimeException
입니다.
에서 변환 byte
을 Byte
라고도 복싱은 발생할 수 있습니다 OutOfMemoryError가 JVM이 힙에 새로운 객체를 할당 할 수 있습니다으로 :
랩퍼 클래스 중 하나 (Boolean, Byte, Character, Short, Integer, Long, Float 또는 Double) 중 하나의 새 인스턴스를 할당해야하고 스토리지가 부족한 경우 복싱 변환으로 인해 OutOfMemoryError가 발생할 수 있습니다.
그 때문에,보다 안전한 byte -> long
확대 변환 이 바람직하다.
답변
올바른 과부하를 찾으려면 순서는 다음과 같습니다.
- 매개 변수 수별
- 복싱 / 언 박스
- 다양한 변수
그래서
- 결과가
b
어디에 있다면 .Byte
Byte, Byte
- 통과했다면
new byte[] { b, b }
결과는 다음과 같습니다byte, byte
. - 두 바이트 (B), 전달 된 경우 확대 롱 INT에 바이트를 행 가능하며 결과이다
long, long
. - 길고 긴 과부하가 제거되면
Byte, Byte
결과가 발생합니다.