Wziąłem ten fragment kodu z jakiegoś quizu, używając IDE wykonałem go i otrzymałem wynik długi, długi, ale poprawna odpowiedź to Bajt, Bajt , dlaczego mam inny wynik? Pytanie dotyczy 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);
}
}
EDYTOWANE:
Kod został pobrany tutaj: Przegląd certyfikacji Oracle i przykładowe pytania (Strona: 13, Pytanie: 5)
Byte b = 5;
to duże B.long, long
Dostaję też Java8 zbyt FYI ... Nie jestem pewien, dlaczego mam być szczery, też czekam na odpowiedź :)Odpowiedzi:
Jeśli więc przejrzysz specyfikację języka Java w celu ustalenia podpisu metody w czasie kompilacji, będzie jasne:
Tak więc z powyższych kroków jasne jest, że w twoim przypadku w pierwszej fazie kompilator Java znajdzie pasującą metodę, która to robi
doCalc(long a,long b)
. Twoja metodadoCalc(Byte s1, Byte s2)
wymaga automatycznego połączenia podczas połączenia, aby uzyskać mniej preferencji.źródło
long
akceptujebyte
, wydaje się podążać za rozszerzającą się prymitywną konwersją : docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.2 . Więc w zasadzie,+widening -boxing -varargs
po czym+widening +boxing -varargs
następnie+widening +boxing +varargs
.Byte, Byte
?Przeczytaj rozdział JLS na temat konwersji .
W twoim przypadku JVM decyduje się na rozszerzenie konwersji,
byte -> long
ponieważ konwersja jest bezpieczniejsza, ponieważ gwarantuje, że nie spowodujeRuntimeException
.Konwersja z
byte
naByte
zwany również boksem może spowodować OutOfMemoryError, ponieważ JVM musi przydzielić nowe obiekty do sterty:Z tego powodu preferowana jest bezpieczniejsza
byte -> long
konwersja poszerzająca .źródło
byte
doByte
nigdy nie powodujeOutOfMemoryException
, ponieważ wszystkie wartościByte
(-128 - 127) są buforowane wewnętrznie. Ale może nie być tak samo z innymi typami, więc zgodnie z ogólną zasadą priorytetem jest poszerzenie konwersji.Aby znaleźć prawidłowe przeciążenie, kolejność jest następująca:
Więc
b
, gdyByte
wynik będzieByte, Byte
.new byte[] { b, b }
wynik byłbybyte, byte
.long, long
.Byte, Byte
wyniki.źródło