Un uso della parola chiave var in C # è la dichiarazione di tipo implicito. Qual è la sintassi equivalente Java per var ?
Un uso della parola chiave var in C # è la dichiarazione di tipo implicito. Qual è la sintassi equivalente Java per var ?
Risposte:
Non c'è nessuno. Purtroppo, devi digitare il nome completo del tipo.
Modifica: 7 anni dopo essere stato pubblicato, l'inferenza del tipo per le variabili locali (con var
) è stata aggiunta in Java 10.
Modifica: 6 anni dopo la pubblicazione, per raccogliere alcuni dei commenti dal basso:
Il motivo per cui C # ha la var
parola chiave è perché è possibile avere tipi senza nome in .NET. Per esempio:
var myData = new { a = 1, b = "2" };
In questo caso, sarebbe impossibile dare un tipo adeguato a myData
. 6 anni fa, questo era impossibile in Java (tutti i tipi avevano nomi, anche se erano estremamente dettagliati e irti). Non so se questo sia cambiato nel frattempo.
var
non è lo stesso di dynamic
. var
I numeri sono ancora digitati staticamente al 100%. Questo non compilerà:
var myString = "foo";
myString = 3;
var
è utile anche quando il tipo è evidente dal contesto. Per esempio:
var currentUser = User.GetCurrent();
Posso dire che in qualsiasi codice di cui sono responsabile, currentUser
contiene una User
classe derivata o. Ovviamente, se la tua implementazione di User.GetCurrent
return an int, allora forse questo è un danno per te.
Questo non ha nulla a che fare con var
, ma se si hanno strane gerarchie ereditarie in cui si ombreggiano i metodi con altri metodi (ad esempio new public void DoAThing()
), non dimenticare che i metodi non virtuali sono influenzati dal Tipo in cui vengono espressi.
Non riesco a immaginare uno scenario del mondo reale in cui questo sia indicativo di un buon design, ma potrebbe non funzionare come previsto:
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
Come indicato, i metodi virtuali non sono interessati da questo.
No, non esiste un modo non semplice per inizializzare un var
senza una variabile effettiva.
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
In questo caso, fallo alla vecchia maniera:
object foo6;
var p = new X(); p.Z()
non è lo stesso SuperX p = new X(); p.Z()
di tutte le X e e SuperX, anche se X : SuperX
. Convar
il tipo statico di p
è sempre X
nel primo esempio sopra, ma sempre SuperX
nel secondo esempio. Una differenza sottile ma importante da tenere presente. Ma la tua risposta è molto corretta :-)
var
non rende il codice meno chiaro. Piuttosto il contrario secondo me. Perché ad esempio scrivere il tipo due (o anche tre) volte sulla stessa riga quando lo si dichiara e si crea un'istanza ( RadioButton radioButton = new RadioButton();
)? var
ti fa piuttosto pensare due volte quando dai un nome alle tue variabili perché focalizza l'attenzione sulla funzionalità piuttosto che sul tipo (ad esempio, UserCollection collection = new userRepository.GetUsers();
piuttosto più naturalmente si trasforma in var users = userRepository.GetUsers();
). Se pensi che var
non sia chiaro, è solo perché inutilizzato.
var
può sicuramente rendere chiaro il codice usato bene, ma può anche renderlo poco chiaro troppo usato male; come molte opzioni di formattazione. Il saldo differisce a seconda di quanto usi oggetti anonimi e generici, nessuno dei quali esisteva in .NET 1.0, rendendolo meno utile come parola chiave ipotetica nella prima versione di C♯. Vorrei solo nominare a RadioButton
radioButton
nel caso di un metodo factory o helper in cui l'unica cosa significativa del pulsante era che era un RadioButton
, altrimenti è una follia con o senza var
.
var
come te, se non di più, ma ho cambiato la mia opinione, e forse è semplice come una domanda di opinioni diverse, perché penso ancora che ti sbagli quando dici che è un importa quanto stai usando oggetti anonimi e generici;) La dichiarazione del tipo è spesso solo rumore del codice, se non riesci a capire il codice senza di esso il codice probabilmente non è chiaro in entrambi i casi.
var
stesso richiede semplicemente al compilatore di dedurre il tipo dall'assegnazione; è zucchero sintattico. All'inizio ero scettico, ma lo uso religiosamente e devo ancora incontrare un momento in cui ha causato confusione. Rimuove la ridondanza durante l'istanza e rimuove la necessità di controllare il tipo quando si fa riferimento. Non esiste un equivalente JAVA al JAVA 9.
Se aggiungi Lombok al tuo progetto puoi usare la sua parola chiave val .
final
non necessariamente immutabile. Considerafinal StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
var
. projectlombok.org/features/experimental/var.html
JEP - Proposta di miglioramento JDK
http://openjdk.java.net/jeps/286
JEP 286: Inferenza di tipo variabile locale
Autore Brian Goetz
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
Ho preparato un plugin per IntelliJ che, in un certo senso, ti dà var
in Java. È un trucco, quindi si applicano le solite dichiarazioni di non responsabilità, ma se usi IntelliJ per il tuo sviluppo Java e vuoi provarlo, è su https://bitbucket.org/balpha/varsity .
Con il rilascio di JDK 10 il 20 marzo, Java ora include un var
nome di tipo riservato (non una parola chiave, vedere di seguito) come specificato in JEP 286 . Per le variabili locali, ora è valido in Java 10 o versioni successive:
var map = new HashMap<String, Integer>();
Il var
nome del tipo riservato in Java è quasi identico alla var
parola chiave in C # in quanto entrambi consentono una digitazione implicita (vedi sotto per differenze importanti). var
in Java può essere utilizzato solo per l'inferenza di tipo implicito nei seguenti contesti (come elencato in JEP 286: Obiettivi ):
Pertanto var
non può essere utilizzato per campi, tipi restituiti, nomi di classe o nomi di interfaccia. La sua logica è quella di eliminare la necessità di includere nomi di tipo lunghi quando si dichiarano e si definiscono variabili locali, come affermato in JEP 286 (scritto da Brian Goetz):
Cerchiamo di migliorare l'esperienza degli sviluppatori riducendo la cerimonia associata alla scrittura del codice Java, pur mantenendo l'impegno di Java per la sicurezza dei tipi statici, consentendo agli sviluppatori di eludere la dichiarazione manifest spesso non necessaria di tipi di variabili locali.
var
Scoping in JavaVa notato che var
non è una parola chiave in Java, ma piuttosto un nome di tipo riservato. Come citato da JEP 286:
L'identificatore var non è una parola chiave; invece è un nome di tipo riservato. Ciò significa che il codice che utilizza var come variabile, metodo o nome del pacchetto non sarà interessato; il codice che utilizza var come nome della classe o dell'interfaccia sarà interessato (ma questi nomi sono rari in pratica, poiché violano le convenzioni di denominazione normali).
Si noti che poiché var
è un nome di tipo riservato e non una parola chiave, può ancora essere utilizzato per nomi di pacchetti, nomi di metodi e nomi di variabili (insieme al nuovo ruolo di interferenza del tipo). Ad esempio, i seguenti sono tutti esempi di usi validi di var
in Java:
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
Come citato da JEP 286:
Questo trattamento sarebbe limitato alle variabili locali con inizializzatori, indici nel for-loop avanzato e locali dichiarati in un for-loop tradizionale; non sarebbe disponibile per formali di metodi, formali di costruttori, tipi di restituzione di metodi, campi, formali di cattura o qualsiasi altro tipo di dichiarazione variabile.
var
Java e C.Questa è una notevole differenza tra var
in C # e Java include quanto segue: var
può essere usato come nome di tipo in C # ma non può essere usato come nome di classe o nome di interfaccia in Java. Secondo la documentazione C # (Variabili locali tipizzate implicitamente) :
Se un tipo denominato
var
rientra nell'ambito, lavar
parola chiave si risolverà in quel nome di tipo e non verrà trattata come parte di una dichiarazione di variabile locale tipizzata in modo implicito.
La possibilità di utilizzare var
come nome di tipo in C # crea una certa complessità e introduce alcune regole di risoluzione complesse, che vengono evitate var
in Java impedendo var
come nome di classe o di interfaccia. Per informazioni sulla complessità dei var
nomi dei tipi in C #, vedere Le restrizioni si applicano alle dichiarazioni di variabili tipizzate in modo implicito . Per ulteriori informazioni sulla logica alla base della decisione di scoping per `var in Java, vedere JEP 286: Scelte di scoping .
var
per i campi o i tipi restituiti? Perché è importante notare?
var
in Java non può essere utilizzato per campi o tipi restituiti. Questo è importante perché questa limitazione rende var
sensibile al contesto, dove può essere utilizzata solo in alcuni contesti (variabili locali) e non in altri. Questa non è necessariamente una differenza tra Java e C # che dovrebbe essere notato, ma un'importante restrizione in generale quando si usa var
in Java.
var
un nome di classe e usarlo come tale. Tecnicamente è una "parola chiave di contesto" in caso di c #, ma in Java sembra che tu non possa fare lo stesso. Correggimi se sbaglio.
var
come nome di classe o nome di interfaccia in Java (che non è comunque comune), ma è possibile utilizzarlo per nomi di variabili, nomi di metodi e nomi di pacchetti. Ad esempio, var var = 1;
è una dichiarazione valida Java ma cercando di dichiarare una classe come public class var {}
si traduce in un errore: as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations
. Ho aggiornato la risposta sopra per approfondire la logica alla base var
di Java e le sue differenze con var
in C #.
Sarà supportato in JDK 10. È anche possibile vederlo in azione nella build di accesso anticipato .
Il JEP 286 :
Migliora il linguaggio Java per estendere l'inferenza del tipo alle dichiarazioni delle variabili locali con gli inizializzatori.
Quindi ora invece di scrivere:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
Scrivi:
var list = new ArrayList<String>();
var stream = myStream();
Appunti:
var
è ora a nome di tipo riservatoSe vuoi provarlo senza installare Java sul tuo sistema locale, ho creato un'immagine Docker con JDK 10 installato su di esso:
$ 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
) non è equivalente. Nel var
esempio list
è di tipo ArrayList
, non una List
.
Una soluzione semplice (supponendo che tu stia utilizzando un IDE decente) è semplicemente digitare 'int' ovunque e quindi farlo impostare per te.
In realtà ho appena aggiunto una classe chiamata 'var', quindi non devo digitare qualcosa di diverso.
Il codice è ancora troppo dettagliato, ma almeno non devi scriverlo!
int
) - Mi sto perdendo qualcosa? (*: mentre non definirei mai Eclipse un IDE decente, non posso giudicare per gli altri ...)
Puoi dare un'occhiata a Kotlin di JetBrains, ma è val. non var.
Java 10 ha ottenuto l'inferenza del tipo di variabile locale, quindi ora ha var
praticamente l'equivalente di C # one (per quanto ne so).
Può anche inferire tipi non denotabili (tipi che non possono essere nominati in quel posto dal programmatore; anche se quali tipi non sono denotabili è diverso). Vedi ad esempio Trucchi con var
e classi anonime (che non dovresti mai usare al lavoro) .
L'unica differenza che ho trovato è che in C #,
In Java 10 var
non è un nome di tipo legale.
Come di Java 10, l'equivalente è ... var
.
So che questo è più vecchio, ma perché non creare una classe var e creare costruttori con tipi diversi e in base a quali costruttori viene invocato si ottiene var con tipo diverso. Potresti persino creare metodi per convertire un tipo in un altro.
Lombok
supporta var ma è ancora classificato come sperimentale:
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);
Ecco una trappola da evitare quando si tenta di utilizzarlo IntelliJ IDEA
. Sembra funzionare come previsto sebbene includa il completamento automatico e tutto. Fino a quando non esiste una soluzione "non confusa" (ad es. Dovuta a JEP 286: Inferenza di tipo variabile locale ), questa potrebbe essere la soluzione migliore in questo momento.
Si noti che val
è anche il supporto Lombok
senza modificare o creare un lombok.config
.
Puoi, in Java 10, ma solo per Local variabili , che significa,
Puoi,
var anum = 10; var aString = "Var";
Ma non posso
var anull = null; // Since the type can't be inferred in this case
Controlla le specifiche per maggiori informazioni.
var
può essere utilizzato per molte forme di tipi non identificabili, inclusi tipi di acquisizione, tipi di intersezione e tipi di classe anonimi. E, a partire da Java 11, può essere applicato anche ai parametri lambda.
In generale puoi usare la classe Object per qualsiasi tipo, ma devi eseguire il cast del tipo in seguito!
per esempio:-
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
parola ora ufficialmente nella lingua, la tua risposta si riferisce anche al modo ormai vecchio stile.
Questa funzione è ora disponibile in Java SE 10. Il var statico e sicuro è finalmente arrivato nel mondo java :)
fonte: https://www.oracle.com/corporate/pressrelease/Java-10-032018.html
val
(ovar
) se si utilizza un particolare linguaggio "sostituzione Java" ;-)