Existe-t-il une inférence de type automatique en Java?

113

Existe-t-il un autotype de variable en Java comme vous l'avez en C ++?

Un exemple:

for ( auto var : object_array)
    std::cout << var << std::endl;

for( auto var : object_array)
    var.do_something_that_only_this_particular_obj_can_do();

Je sais qu'il existe une boucle for améliorée en Java, mais y a-t-il une auto? Sinon, y a-t-il un hack pour faire cela? Je fais référence à la nouvelle fonctionnalité de C ++ 11

Jeux Brainiac
la source
1
Tout sauf les types fondamentaux peut être affecté à une variable de type Object, donc pour certaines opérations, vous pouvez utiliser Objectoù vous le souhaitez auto.
Zyx 2000
1
aucun java n'a pas de telle variable
Aleksei Bulgak
@ Zyx2000: Ensuite, il utilisera la to_stringfonction de l'objet , et non l'objet réel en question, n'est-ce pas?
Jeux Brainiac
2
@GamesBrainiac: Non, il utilisera la version remplacée, s'il en existe une.
Keppil
2
Le terme que vous recherchez n'est pas "auto", c'est "inférence de type". Il y a pas mal de questions sur l'inférence de type en Java, bien qu'elles se réfèrent principalement à des génériques, donc je ne sais pas comment trouver un doublon ...

Réponses:

49

Répondu avant la modification de la question :

Non, il n'y a pas de autotype de variable en Java. La même boucle peut être réalisée comme:

for ( Object var : object_array)
  System.out.println(var);

Java a des variables locales, dont la portée est dans le bloc où elles ont été définies. Similaire à C et C ++, mais il n'y a pas de mot clé auto ou register. Cependant, le compilateur Java ne permettra pas l'utilisation d'une variable locale non explicitement initialisée et donnera une erreur de compilation (contrairement à C et C ++ où le compilateur ne donnera généralement qu'un avertissement). Gracieuseté: Wikipedia .

Non, il n'y a pas d'inférence de type traditionnelle en Java comme C ++. Il y avait un RFE mais celui-ci a été fermé comme "Ne résoudra pas", la raison invoquée était:

Les humains bénéficient de la redondance de la déclaration de type de deux manières. Tout d'abord, le type redondant sert de documentation précieuse - les lecteurs n'ont pas à rechercher la déclaration de getMap () pour savoir quel type elle renvoie. Deuxièmement, la redondance permet au programmeur de déclarer le type voulu, et ainsi de bénéficier d'une vérification croisée effectuée par le compilateur.

CORNICHON
la source
10
@GamesBrainiac Non, les appels de méthode sont toujours polymorphes en Java. Cependant, beaucoup d'autres choses (par exemple, la résolution de surcharge, ou toute opération non définie sur Object) ne peuvent pas être faites comme ça. Ce n'est pas vraiment une bonne réponse, cela ne fonctionne que parce que l'exemple de la question est faible.
10
Cette question concerne l'inférence de type en C ++ 11, pas l'ancienne utilisation de autoC et pré-C ++ 11. Votre modification est hors sujet.
4
"Ce n'est pas ce que je voulais dire, une fois que vous l'aurez tapé en un objet, cela vous donnera la chaîne de caractères de l'objet" False. Absolument 100% faux.
Louis Wasserman
140
"Les humains bénéficient de la redondance." C'est vrai. Chaque matin, je me réveille et je pense "comment puis-je rendre mon code plus redondant?". En raison des avantages.
ahoffer
2
De plus cette réponse est obsolète car varc'est un mot-clé réservé depuis Java 9.
6infinity8
69

Peut-être que Java 10 a ce que vous (et moi) voulons, grâce au varmot - clé.

var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>

À partir des propositions d'amélioration JDK 286


Mise à jour: Oui, cette fonctionnalité a été intégrée à la version Java 10!

désolé missjackson
la source
6
C'est une amélioration, mais ce mot-clé ne peut fonctionner qu'avec des variables locales. Pas aussi puissant que l'inférence de type automatique C ++
Texasbruce
7
Petite petite pioche: ce varn'est pas un mot-clé! Du JLS : "var n'est pas un mot-clé, mais plutôt un identifiant avec une signification spéciale comme le type d'une déclaration de variable locale". Ainsi, contrairement aux mots-clés, rien ne vous empêche d'appeler une variable ou une méthode "var".
Klitos Kyriacou
2
Bon point @KlitosKyriacou. Pourtant, si j'imagine remplacer «mot-clé» par «identifiant» - ou même «identifiant avec une signification spéciale comme type de déclaration de variable locale» - la réponse serait moins claire, je pense. Mais oui, varn'est en effet pas dans la liste des mots-clés.
sorrymissjackson
Ce n'est pas un mot clé simplement pour la compatibilité descendante. Outre le fait que vous pouvez avoir un identifiant avec ce nom, var joue le rôle d'un mot-clé.
facetus le
25

Java 7 introduit la syntaxe du diamant

Box<Integer> integerBox = new Box<>(); // Java 7

Par rapport à l'ancien java

Box<Integer> integerBox = new Box<Integer>(); // Before Java 7

Le lecteur critique remarquera que cette nouvelle syntaxe n'aide pas à écrire les boucles for dans la question d'origine. Cela semble correct et tout à fait intentionnel. Voir l'autre réponse qui cite la base de données de bogues d'Oracle.

Tarrasch
la source
4
C'est vrai, mais ce que lui (et moi) recherchons est quelque chose comme auto integerBox = new Box<Integer>();HashMap<String, LinkedList<Operation, Set<Integer>>>
:,
1
Cette préoccupation est exactement ce que j'ai abordé après les exemples de code. La conclusion est que Java ne fait pas cela, et c'est exprès.
Tarrasch
18

Dans Java 8, vous pouvez utiliser l'inférence de type lambda pour éviter de déclarer le type. L'analogue aux exemples de l'interrogateur serait:

object_array.forEach(var -> System.out.println(var)); 
object_array.forEach(var -> var.do_something_that_only_this_particular_obj_can_do());

qui peuvent également être simplifiés à l'aide de références de méthode:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);
Ajit George
la source
8

En bref, non, il n'y a pas de type automatique. Si tout ce que vous faites est d'imprimer la valeur, vous pouvez simplement vous référer à la valeur comme un Object.

SimonC
la source
ou calculer des hashCodes, ou collecter des noms de classes, ou ... vous avez l'idée;) La liste est cependant courte. Voir la documentation de la classe Object (commentaire destiné aux débutants, je suis sûr que vous le saviez SimonC)
Alexander Malakhov
4

Ce n'est pas une solution Java pure, cependant l'ajout d'une bibliothèque appelée lombok permettra à la magie ci-dessous de compiler et de fonctionner de manière très similaire au automot-clé en C ++

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
samvel1024
la source