web-dev-qa-db-fra.com

Est-ce que l'utilisation de var avec un résultat littéral dans une classe wrapper primitive ou primitive?

Après avoir lu et parlé de Java 10s nouveau nom de type réservé var ( JEP 286: Inférence de type variable locale ), une question s'est posée au cours de la discussion.

Lorsque vous l'utilisez avec des littéraux comme:

var number = 42;

est number maintenant un int ou un Integer? Si vous l'utilisez simplement avec des opérateurs de comparaison ou en tant que paramètre, cela n'a généralement pas d'importance grâce à l'autoboxing et au -unboxing. Mais en raison des fonctions membres de Integers, cela pourrait avoir de l'importance.

Alors, quel type est créé par var, une primitive int ou une classe Integer?

33
sweisgerber.dev

var demande au compilateur de déduire le type de la variable du type de l'initialiseur et le type naturel de 42 est int. Donc number sera un int. C'est ce que le l'exemple JLS dit :

var a = 1;  // a has type 'int' 

Et je serais surpris si cela fonctionnait d'une autre manière, quand j'écris quelque chose comme ça, je m'attends définitivement à une primitive.

Si vous avez besoin d'un var comme primitive encadrée, vous pouvez faire:

var x = (Integer) 10;  // x is now an Integer
31
Eugene

Selon le changements de spécifications proposés dans 14.4.1 Déclarateurs et types de variables locales :

Si LocalVariableType est var, alors laissez [~ # ~] t [~ # ~] être le type de l'expression d'initialisation lorsqu'elle est traitée comme si elle n'apparaissait pas dans un contexte d'affectation, et était donc une expression autonome ( 15.2 ). Le type de la variable locale est la projection vers le haut de [~ # ~] t [~ # ~] par rapport à toutes les variables de type synthétique mentionnées par [~ # ~] t [~ # ~] (4.10.5).

En d'autres termes, le type déduit pour la variable locale est le type que l'expression d'initialisation aurait si elle était utilisée comme expression autonome. 42 comme expression autonome a le type int, ergo, la variable number est de type int.

La projection vers le haut est un terme défini dans les changements de spécifications qui ne s'applique pas à des cas simples comme celui-ci.

10
Jörg W Mittag

Testons-le. Avec jshell:

jshell> Integer boxed1 = 42000;
boxed1 ==> 42000

jshell> Integer boxed2 = 42000;
boxed2 ==> 42000

jshell> System.out.println(boxed1 == boxed2);
false

jshell> var infered1 = 42000;
infered1 ==> 42000

jshell> var infered2 = 42000;
infered2 ==> 42000

jshell> System.out.println(infered1 == infered2);
true

Dans la première comparaison, les deux variables ne sont pas identiques; ce sont des instances différentes. La deuxième comparaison est cependant vraie, donc un int doit avoir été déduit ici.

Remarque: Pour l'essayer à la maison, utilisez des valeurs extérieures à <-128, 128). Les instances entières de cette plage sont mises en cache.

7
david a.

Le compilateur traite var number = 42; Similaire à int number = 42;

public void method(Integer i) {
    System.out.print("Integer method");
}
public void method(int i) {
    System.out.print("int method");
}

var n = 42; // n has type 'int' 
method(n); // => "int method"

Et la boxe automatique lorsque:

public void method(Integer i) {
    System.out.print("Integer method");
}

var n = 42; // a has type 'int'
method(n); // => "Integer method"
1
tonyhoan