Une utilisation du mot clé var en C # est la déclaration de type implicite. Quelle est la syntaxe équivalente Java pour var ?
Il n'y en a pas. Hélas, vous devez taper le nom du type complet.
Edit: 7 ans après la publication, l’inférence de type pour les variables locales (avec var
) a été ajoutée dans Java 10.
Éditer: 6 ans après avoir été posté, pour recueillir certains des commentaires ci-dessous:
La raison pour laquelle C # a le mot clé var
est qu’il est possible d’avoir des types qui n’ont pas de nom dans .NET. Par exemple:
var myData = new { a = 1, b = "2" };
Dans ce cas, il serait impossible de donner un type approprié à myData
. Il y a 6 ans, cela était impossible en Java (tous les types avaient des noms, même s'ils étaient extrêmement prolixes et inconsidérés). Je ne sais pas si cela a changé entre-temps.
var
n'est pas la même chose que dynamic
. var
iables sont toujours typés statiquement à 100%. Cela ne compilera pas:
var myString = "foo";
myString = 3;
var
est également utile lorsque le type est évident du contexte. Par exemple:
var currentUser = User.GetCurrent();
Je peux dire que dans tout code dont je suis responsable, currentUser
contient une User
ou une classe dérivée. Évidemment, si votre implémentation de User.GetCurrent
renvoie un int, alors peut-être que cela vous nuit.
Cela n'a rien à voir avec var
, mais si vous avez des hiérarchies d'héritage étranges dans lesquelles vous masquez les méthodes avec d'autres méthodes (par exemple, new public void DoAThing()
), n'oubliez pas que les méthodes non virtuelles sont affectées par le type sous lequel elles sont exprimées.
Je ne peux pas imaginer de scénario réel dans lequel cela indique une bonne conception, mais cela risque de ne pas fonctionner comme prévu:
class Foo {
public void Non() {}
public virtual void Virt() {}
}
class Bar : Foo {
public new void Non() {}
public override void Virt() {}
}
class Baz {
public static Foo GetFoo() {
return new Bar();
}
}
var foo = Baz.GetFoo();
foo.Non(); // <- Foo.Non, not Bar.Non
foo.Virt(); // <- Bar.Virt
var bar = (Bar)foo;
bar.Non(); // <- Bar.Non, not Foo.Non
bar.Virt(); // <- Still Bar.Virt
Comme indiqué, les méthodes virtuelles ne sont pas affectées par cela.
Non, il n'y a pas de moyen non maladroit pour initialiser une var
sans variable réelle.
var foo1 = "bar"; //good
var foo2; //bad, what type?
var foo3 = null; //bad, null doesn't have a type
var foo4 = default(var); //what?
var foo5 = (object)null; //legal, but go home, you're drunk
Dans ce cas, il suffit de le faire à l'ancienne:
object foo6;
Si vous ajoutez Lombok à votre projet, vous pouvez utiliser son mot clé val.
PEC - Proposition d'amélioration du JDK
http://openjdk.Java.net/jeps/286
PEC 286: Inférence de type de variable locale
Auteur Brian Goetz
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
J'ai concocté un plugin pour IntelliJ qui - d'une certaine manière - vous donne var
en Java. C'est un hack, donc les clauses de non-responsabilité habituelles s'appliquent, mais si vous utilisez IntelliJ pour votre développement Java et que vous voulez l'essayer, il se trouve à https://bitbucket.org/balpha/varsity .
Avec la sortie de JDK 10 le 20 mars, Java inclut désormais un nom de type réservé var
(et non un mot clé - voir ci-dessous), comme indiqué dans JEP 286 . Pour les variables locales, les éléments suivants sont désormais valables dans Java 10 ou supérieur:
var map = new HashMap<String, Integer>();
Le nom du type réservé var
en Java est presque identique au mot clé var
en C # en ce sens que les deux permettent le typage implicite (voir ci-dessous les différences importantes). var
en Java ne peut être utilisé que pour l'inférence de type implicite dans les contextes suivants (énumérés dans JEP 286: Objectifs ):
Par conséquent, var
ne peut pas être utilisé pour les champs, les types de retour, les noms de classe ou les noms d'interface. Son objectif est de supprimer la nécessité d'inclure des noms de type longs lors de la déclaration et de la définition de variables locales, comme indiqué dans JEP 286 (écrit par Brian Goetz):
Nous cherchons à améliorer l'expérience des développeurs en réduisant la cérémonie associé à l'écriture de code Java, tout en maintenant l'engagement de Java à la sécurité de type statique, en permettant aux développeurs d'élire le déclaration manifeste souvent inutile de types de variables locales.
var
Portée en Java
Il convient de noter que var
n'est pas un mot clé en Java, mais un nom de type réservé. Cité dans le JEP 286:
L'identifiant var n'est pas un mot clé. à la place, il s'agit d'un type réservé prénom. Cela signifie que le code qui utilise var en tant que variable, méthode ou le nom du paquet ne sera pas affecté; code qui utilise var en tant que classe ou Le nom d'interface sera affecté (mais ces noms sont rares dans la pratique, car ils violent les conventions de nommage habituelles).
Notez que, comme var
est un nom de type réservé et non un mot-clé, il peut toujours être utilisé pour les noms de packages, les noms de méthodes et les noms de variables (avec son nouveau rôle d'interférence de type). Par exemple, vous trouverez ci-dessous des exemples d'utilisations valides de var
en Java:
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
Cité dans le JEP 286:
Ce traitement serait limité aux variables locales avec les initialiseurs, les index dans la boucle for améliorée et les locales déclarées dans une boucle traditionnelle; il ne serait pas disponible pour les méthodes formelles, constructals formals, types de méthode, champs, captures, ou tout autre type de déclaration de variable.
Différences entre var
en Java & C #
Il existe une différence notable entre var
en C # et Java, notamment les suivants: var
peut être utilisé comme nom de type en C # mais ne peut pas être utilisé comme nom de classe ou d’interface en Java. Selon la documentation C # (variables locales implicitement typées) :
Si un type nommé
var
se trouve dans la portée, le mot clévar
sera résolu en ce nom de type et ne sera pas traité comme faisant partie d’un. implicitement typé déclaration de variable locale.
La possibilité d'utiliser var
comme nom de type en C # crée une certaine complexité et introduit des règles de résolution complexes, qui sont évitées par var
en Java en interdisant var
en tant que nom de classe ou d'interface. Pour plus d'informations sur les complexités des noms de types var
en C #, voir Les restrictions s'appliquent aux déclarations de variable de type implicite . Pour plus d'informations sur les raisons qui ont motivé la décision de portée de `var en Java, voir PEC 286: Choix de la portée .
Il sera pris en charge dans JDK 10. Il est même possible de le voir en action dans le fichier early access build .
Le JEP 286 :
Améliorez le langage Java pour étendre l'inférence de type aux déclarations de variables locales avec des initialiseurs.
Alors maintenant, au lieu d'écrire:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
Vous écrivez:
var list = new ArrayList<String>();
var stream = myStream();
Remarques:
var
est maintenant un nom de type réservéSi vous voulez l'essayer sans installer Java sur votre système local, j'ai créé une image Docker avec JDK 10 installée:
$ docker run -it marounbassam/ubuntu-Java10 bash
root@299d86f1c39a:/# jdk-10/bin/jshell
Mar 30, 2018 9:07:07 PM Java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
| Welcome to JShell -- Version 10
| For an introduction type: /help intro
jshell> var list = new ArrayList<String>();
list ==> []
Une solution simple (en supposant que vous utilisez un IDE décent) consiste à taper 'int' partout et à le faire définir ensuite.
En fait, je viens juste d'ajouter une classe appelée 'var' pour ne pas avoir à taper quelque chose de différent.
Le code est encore trop bavard, mais au moins vous n’avez pas à le taper!
Java 10 a obtenu l'inférence de type de variable locale, donc maintenant il a var
qui est à peu près équivalent à celui de C # (pour autant que je sache).
Il peut également déduire des types non dénotables (types que le programmeur n'a pas pu nommer à cet endroit; bien que quels types ne soient pas dénotables, c'est différent, par exemple Java n'a pas d'équivalent aux types anonymes C #) .
La seule différence que j'ai pu trouver est que dans C #,
En Java 10, var
n'est pas un nom de type légal.
Vous pouvez regarder Kotlin par JetBrains, mais c’est val. pas var.
Je sais que c'est plus ancien, mais pourquoi ne pas créer une classe var et créer des constructeurs avec différents types et en fonction du type de constructeur appelé, vous obtenez var avec un type différent Vous pouvez même intégrer des méthodes pour convertir un type en un autre.
A partir de Java 10, l'équivalent est ... var
.
Lombok
supporte var mais il reste classé comme expérimental:
import lombok.experimental.var;
var number = 1; // Inferred type: int
number = 2; // Legal reassign since var is not final
number = "Hi"; // Compilation error since a string cannot be assigned to an int variable
System.out.println(number);
Ici est un piège à éviter lorsque vous essayez de l'utiliser dans IntelliJ IDEA
. Il semble que cela fonctionne comme prévu, y compris l'auto-complétion et tout. Tant qu’il n’existera pas de solution "non-informatique" (p. Ex. En raison de JEP 286: Inférence de type de variable locale ), cela pourrait être votre meilleur choix pour le moment.
Notez que val
est également pris en charge par Lombok
sans modification ni création de lombok.config
.
Vous pouvez, en Java 10, mais seulement pour les variables Local, ce qui signifie
Vous pouvez,
var anum = 10; var aString = "Var";
Mais ne peut pas,
var anull = null; // Since the type can't be inferred in this case
Découvrez le spec pour plus d'informations.
En général, vous pouvez utiliser la classe Object pour n’importe quel type, mais vous aurez le transtype plus tard!
par exemple:-
Object object = 12;
Object object1 = "Aditya";
Object object2 = 12.12;
System.out.println(Integer.parseInt(object.toString()) + 2);
System.out.println(object1.toString() + " Kumar");
System.out.println(Double.parseDouble(object2.toString()) + 2.12);