J'ai pris cet extrait de code d'un quiz, en utilisant IDE je l'ai exécuté et j'obtiens un résultat long, long mais la bonne réponse est Byte, Byte , pourquoi j'ai obtenu un résultat différent? La question est liée à 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);
}
}
ÉDITÉ:
Le code a été pris ici: Présentation de la certification Oracle et exemples de questions (page: 13, question: 5)
Byte b = 5;
avec un B majuscule?long, long
aussi Java8 pour info ... Je ne sais pas pourquoi pour être honnête, j'attends aussi une réponse :)Réponses:
Alors, si vous passez par le langage Java spécification pour déterminer la signature de la méthode au moment de la compilation , il sera clair:
Ainsi, à partir des étapes ci-dessus, il est clair que dans votre cas, dans la première phase, le compilateur Java trouvera une méthode de correspondance qui le fait
doCalc(long a,long b)
. Votre méthode adoCalc(Byte s1, Byte s2)
besoin d'un autoboxing pendant l'appel, donc elle aura moins de préférence.la source
long
acceptebyte
, semble suivre une conversion primitive élargie : docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.2 . Donc , fondamentalement,+widening -boxing -varargs
puis+widening +boxing -varargs
ensuite+widening +boxing +varargs
.Byte, Byte
?Veuillez lire le chapitre JLS sur les conversions .
Ce qui se passe dans votre cas, c'est que pendant l'exécution, la machine virtuelle Java choisit d'effectuer une conversion d'élargissement
byte -> long
car cette conversion est plus sûre car il est garanti qu'elle ne provoque pasRuntimeException
.La conversion de
byte
àByte
également appelée boxe peut entraîner OutOfMemoryError car la JVM doit allouer de nouveaux objets sur le tas:Pour cette raison, la
byte -> long
conversion d'élargissement plus sûre est préférée.la source
byte
àByte
ne provoque jamaisOutOfMemoryException
, car toutes les valeurs deByte
(-128 - 127) sont mises en cache en interne. Mais il peut ne pas être le même avec d'autres types, donc comme règle générale, l'élargissement de la conversion devient prioritaire.Pour trouver la surcharge correcte, la commande est:
Donc
b
oùByte
le résultat seraitByte, Byte
.new byte[] { b, b }
le résultat seraitbyte, byte
.long, long
.Byte, Byte
résulte.la source