[java] 오버로드 된 메소드에 바이트 인수 전달

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 언어 사양살펴보면 분명합니다.

  1. 첫 번째 단계 (§15.12.2.2)는 복싱 또는 언 박싱 변환을 허용하거나 가변 arity 메소드 호출을 사용하지 않고 과부하 해결을 수행합니다. 이 단계에서 적용 가능한 방법을 찾지 못하면 처리는 두 번째 단계로 계속 진행됩니다.

  2. 두 번째 단계 (§15.12.2.3)는 복싱 및 언 박싱을 허용하면서 과부하 해결을 수행하지만 가변 arity 메소드 호출의 사용은 여전히 ​​금지합니다. 이 단계에서 적용 가능한 방법을 찾지 못하면 처리는 세 번째 단계로 계속 진행됩니다.

  3. 세 번째 단계 (§15.12.2.4)에서는 과부하를 다양한 arity 방법, boxing 및 unboxing과 결합 할 수 있습니다.

따라서 위의 단계에서 첫 번째 단계에서 Java 컴파일러는 다음과 같은 일치하는 메소드를 찾을 것 doCalc(long a,long b)입니다. 당신의 방법 doCalc(Byte s1, Byte s2)은 호출하는 동안 자동 박스가 필요하므로 덜 선호됩니다.


답변

변환에 대한 JLS 장을 읽으십시오 .

귀하의 경우에 일어나는 일은 런타임 동안 JVM이 확장 변환 을 수행하기로 선택 byte -> long한다는 것 RuntimeException입니다.

에서 변환 byteByte라고도 복싱은 발생할 수 있습니다 OutOfMemoryError가 JVM이 힙에 새로운 객체를 할당 할 수 있습니다으로 :

랩퍼 클래스 중 하나 (Boolean, Byte, Character, Short, Integer, Long, Float 또는 Double) 중 하나의 새 인스턴스를 할당해야하고 스토리지가 부족한 경우 복싱 변환으로 인해 OutOfMemoryError가 발생할 수 있습니다.

그 때문에,보다 안전한 byte -> long 확대 변환 이 바람직하다.


답변

올바른 과부하를 찾으려면 순서는 다음과 같습니다.

  1. 매개 변수 수별
  2. 복싱 / 언 박스
  3. 다양한 변수

그래서

  • 결과가 b어디에 있다면 .ByteByte, Byte
  • 통과했다면 new byte[] { b, b }결과는 다음과 같습니다 byte, byte.
  • 두 바이트 (B), 전달 된 경우 확대 롱 INT에 바이트를 행 가능하며 결과이다 long, long.
  • 길고 긴 과부하가 제거되면 Byte, Byte결과가 발생합니다.

답변