Une utilisation du mot clé var en C # est la déclaration de type implicite. Quelle est la syntaxe équivalente Java pour var ?
Une utilisation du mot clé var en C # est la déclaration de type implicite. Quelle est la syntaxe équivalente Java pour var ?
Réponses:
Il n'y en a pas. Hélas, vous devez taper le nom complet du type.
Edit: 7 ans après avoir été publié, l'inférence de type pour les variables locales (avec var
) a été ajoutée dans Java 10.
Edit: 6 ans après avoir été posté, pour recueillir certains des commentaires ci-dessous:
La raison pour laquelle C # a le var
mot-clé est qu'il est possible d'avoir des types sans 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 bavards et peu bavards). Je ne sais pas si cela a changé entre-temps.
var
n'est pas le même que dynamic
. var
Les variables sont toujours 100% typées statiquement. Cela ne compilera pas:
var myString = "foo";
myString = 3;
var
est également utile lorsque le type est évident dans le contexte. Par exemple:
var currentUser = User.GetCurrent();
Je peux dire que dans n'importe quel code dont je suis responsable, il currentUser
contient une User
classe ou une classe dérivée. Évidemment, si votre implémentation de User.GetCurrent
return retourne un int, alors c'est peut-être un inconvénient pour vous.
Cela n'a rien à voir avec var
, mais si vous avez d'étranges hiérarchies d'héritage où vous masquez des 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 converties.
Je ne peux pas imaginer un scénario du monde réel où cela indique une bonne conception, mais cela peut 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 aucun moyen non maladroit d'initialiser un 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, faites-le à l'ancienne:
object foo6;
var p = new X(); p.Z()
n'est pas le même que SuperX p = new X(); p.Z()
pour tous les X et et SuperX, même si X : SuperX
. Avec var
le type statique de p
est toujours X
dans le premier exemple ci-dessus, mais toujours SuperX
dans le deuxième exemple. Une différence subtile mais importante à prendre en compte. Mais votre réponse est très correcte :-)
var
ne rend pas le code moins clair. Plutôt le contraire à mon avis. Pourquoi par exemple écrire le type deux (ou même trois) fois sur la même ligne lorsque vous le déclarez et l'instanciez ( RadioButton radioButton = new RadioButton();
)? var
vous fait plutôt réfléchir à deux fois lorsque vous nommez vos variables car cela met l'accent sur la fonctionnalité plutôt que sur le type (par exemple, UserCollection collection = new userRepository.GetUsers();
se transforme plus naturellement en var users = userRepository.GetUsers();
). Si vous pensez que ce var
n'est pas clair, c'est simplement parce que vous n'y êtes pas habitué.
var
peut très certainement rendre le code clair bien utilisé, mais il peut aussi le rendre mal utilisé trop mal; comme de nombreuses options de formatage. L'équilibre varie en fonction de l'utilisation que vous faites des objets anonymes et des génériques, qui n'existaient ni dans .NET 1.0, ce qui le rend moins utile comme mot clé hypothétique dans la première version de C♯. Je ne nommerais un RadioButton
radioButton
dans le cas d'une méthode d'usine ou d'aide où la seule chose importante sur le bouton était qu'il s'agissait d'un RadioButton
, sinon c'est de la folie avec ou sans var
.
var
que vous, sinon plus, mais j'ai changé d'avis, et c'est peut-être aussi simple qu'une question d'opinions différentes, parce que je pense toujours que vous vous trompez quand vous dites que c'est un peu importe combien vous utilisez des objets anonymes et génériques;) La déclaration de type est le plus souvent juste du bruit de code, si vous ne pouvez pas comprendre le code sans lui, le code n'est probablement pas clair dans les deux cas.
var
lui-même demande simplement au compilateur de déduire le type de l'affectation; c'est du sucre syntaxique. J'en étais sceptique au début, mais je l'utilise religieusement et je n'ai pas encore rencontré un moment où cela a causé de la confusion. Il supprime la redondance lors de l'instanciation et supprime la nécessité de vérifier le type lors du référencement. Il n'y a pas d'équivalent JAVA en date de JAVA 9.
Si vous ajoutez Lombok à votre projet, vous pouvez utiliser son mot-clé val .
final
ne sont pas nécessairement immuables. Considérezfinal StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
var
. projectlombok.org/features/experimental/var.html
JEP - Proposition d'amélioration du JDK
http://openjdk.java.net/jeps/286
JEP 286: Inférence de type 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 - en quelque sorte - 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, c'est sur https://bitbucket.org/balpha/varsity .
Avec la sortie de JDK 10 le 20 mars, Java inclut désormais un var
nom de type réservé (pas un mot-clé - voir ci-dessous) comme spécifié dans JEP 286 . Pour les variables locales, ce qui suit est maintenant valide dans Java 10 ou supérieur:
var map = new HashMap<String, Integer>();
Le var
nom de type réservé en Java est presque identique au var
mot - clé en C # dans la mesure où les deux permettent une saisie implicite (voir ci-dessous pour les différences importantes). var
en Java ne peut être utilisé pour l'inférence de type implicite que dans les contextes suivants (comme énuméré 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. Sa raison d'être 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 (rédigé par Brian Goetz):
Nous cherchons à améliorer l'expérience des développeurs en réduisant la cérémonie associée à l'écriture de code Java, tout en maintenant l'engagement de Java envers la sécurité des types statiques, en permettant aux développeurs d'éluder la déclaration manifeste souvent inutile des types de variables locales.
var
Portée en JavaIl convient de noter qu'il var
ne s'agit pas d'un mot clé en Java, mais plutôt d'un nom de type réservé. Comme cité dans JEP 286:
L'identifiant var n'est pas un mot-clé; il s'agit plutôt d'un nom de type réservé. Cela signifie que le code qui utilise var comme variable, méthode ou nom de package ne sera pas affecté; le code qui utilise var comme nom de classe ou d'interface sera affecté (mais ces noms sont rares dans la pratique, car ils violent les conventions de dénomination habituelles).
Notez que puisqu'il var
s'agit d'un nom de type réservé et non d'un mot-clé, il peut toujours être utilisé pour les noms de package, les noms de méthode et les noms de variable (avec son nouveau rôle d'interférence de type). Par exemple, ce qui suit sont tous des exemples d'utilisations valides de var
Java:
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
Comme cité dans JEP 286:
Ce traitement serait limité aux variables locales avec des initialiseurs, des index dans la boucle for améliorée et des sections locales déclarées dans une boucle for traditionnelle; il ne serait pas disponible pour les formals de méthode, les formals de constructeur, les types de retour de méthode, les champs, les formals catch ou tout autre type de déclaration de variable.
var
Java et CIl s'agit d'une différence notable entre var
C # et Java, notamment: var
peut être utilisé comme nom de type en C # mais ne peut pas être utilisé comme nom de classe ou nom d'interface en Java. Selon la documentation C # (Variables locales implicitement typées) :
Si un type nommé
var
est dans la portée, levar
mot - clé se résoudra en ce nom de type et ne sera pas traité comme faisant partie d'une déclaration de variable locale implicitement typée.
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 en var
tant que nom de classe ou d'interface. Pour plus d'informations sur la complexité des var
noms de type en C #, consultez Restrictions s'appliquent aux déclarations de variable implicitement typées . Pour plus d'informations sur la justification de la décision de délimitation de `var en Java, voir JEP 286: Choix de délimitation .
var
pour les champs ou les types de retour? Pourquoi est-il important de le noter?
var
en Java ne peut pas être utilisé pour les champs ou les types de retour. Ceci est important car cette restriction rend le var
contexte sensible, où il ne peut être utilisé que dans certains contextes (variables locales) et pas dans d'autres. Ce n'est pas nécessairement une différence entre Java et C # qui doit être notée, mais une restriction importante en général lors de l'utilisation var
en Java.
var
un nom de classe et l'utiliser comme tel. Techniquement, c'est un "mot-clé contextuel" en cas de c #, mais en Java il semble que vous ne puissiez pas faire de même. Corrige moi si je me trompe.
var
comme nom de classe ou nom d'interface en Java (ce qui n'est pas courant de toute façon), mais vous pouvez l'utiliser pour les noms de variable, les noms de méthode et les noms de package. Par exemple, var var = 1;
est une instruction Java valide , mais en essayant de déclarer une classe comme public class var {}
résultat une erreur: as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations
. J'ai mis à jour la réponse ci-dessus pour entrer plus en détail sur la raison d'être var
de Java et ses différences avec var
C #.
Il sera pris en charge dans JDK 10. Il est même possible de le voir en action dans la version à accès anticipé .
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é dessus:
$ 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 ==> []
var
) n'est pas équivalent. Dans l' var
exemple list
est de type ArrayList
, pas a List
.
Une solution simple (en supposant que vous utilisez un IDE décent) consiste simplement à taper «int» partout, puis à le définir pour vous.
En fait, je viens d'ajouter une classe appelée «var», donc je n'ai pas à taper quelque chose de différent.
Le code est encore trop verbeux, mais au moins vous n'avez pas besoin de le taper!
int
) - est-ce que je manque quelque chose? (*: alors que je n'appellerais jamais Eclipse un IDE décent, je ne peux pas juger pour les autres ...)
Java 10 a obtenu une inférence de type de variable locale, alors maintenant il a var
ce 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 qui ne peuvent pas être nommés à cet endroit par le programmeur; bien que les types non dénotables soient différents). Voir par exemple les astuces avec var
et les classes anonymes (que vous ne devriez jamais utiliser au travail) .
La seule différence que j'ai pu trouver est qu'en C #,
En Java 10 var
n'est pas un nom de type légal.
A partir de Java 10, l'équivalent est ... 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 des constructeurs invoqués, vous obtenez var avec un type différent. Vous pouvez même intégrer des méthodes pour convertir un type en un autre.
Lombok
prend en charge var mais il est toujours 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);
Voici un piège à éviter lorsque vous essayez de l'utiliser dans IntelliJ IDEA
. Il semble fonctionner comme prévu, y compris l'achèvement automatique et tout. Jusqu'à ce qu'il existe une solution "non hacky" (par exemple en raison de JEP 286: Inférence de type variable locale ), cela pourrait être votre meilleur pari en ce moment.
Notez que la val
prise en charge par Lombok
ainsi sans modifier ou créer un fichier lombok.config
.
Vous pouvez, dans Java 10, mais uniquement pour les variables locales , ce qui signifie,
Vous pouvez,
var anum = 10; var aString = "Var";
Mais je ne peux pas,
var anull = null; // Since the type can't be inferred in this case
Consultez les spécifications pour plus d'informations.
var
peut être utilisé pour de nombreuses formes de types non dénotables, y compris les types de capture, les types d'intersection et les types de classe anonymes. Et, à partir de Java 11, il peut également être appliqué aux paramètres lambda.
En général, vous pouvez utiliser la classe Object pour n'importe quel type, mais vous devez effectuer une conversion de type 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);
var
mot maintenant officiellement dans la langue, votre réponse fait également référence à la manière désormais démodée.
Cette fonctionnalité est désormais disponible dans Java SE 10. Le var statique, sans danger pour les types, est enfin entré dans le monde java :)
source: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
val
(ouvar
) si vous utilisez un langage "de remplacement Java" particulier ;-)