web-dev-qa-db-fra.com

Quel est l'équivalent du mot clé "var" C # en Java?

Une utilisation du mot clé var en C # est la déclaration de type implicite. Quelle est la syntaxe équivalente Java pour var ?

243
Arturo

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. variables 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;
    
231
Mike Caron

Si vous ajoutez Lombok à votre projet, vous pouvez utiliser son mot clé val.

http://projectlombok.org/features/val.html

43
darthtrevino

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>
25
blueberry0xff

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 .

20
balpha

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 ):

  • variables locales avec initialiseurs
  • index dans la boucle for améliorée
  • les sections locales déclarées dans une boucle for traditionnelle

Par conséquent, varne 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 .

13
Justin Albano

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é
  • Java est still un engagement envers le typage statique!
  • Il ne peut être utilisé que dans les déclarations de variables locales

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 ==> []
11
Maroun

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!

8
JonnyRaa

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 #,

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'une déclaration de variable locale implicitement typée.

En Java 10, var n'est pas un nom de type légal.

5
Alexey Romanov

Vous pouvez regarder Kotlin par JetBrains, mais c’est val. pas var.

5
Artiom

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. 

3
Sebastian Zaba

A partir de Java 10, l'équivalent est ... var

3
Brian Goetz

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.

3
BullyWiiPlaza

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.

2
Antho Christen

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);
0
Aditya Kumar