Esiste l'inferenza automatica del tipo in Java?


113

C'è un autotipo di variabile in Java come quello che hai in C ++?

Un esempio:

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();

So che esiste un ciclo for migliorato in Java, ma esiste un'auto? In caso contrario, c'è un trucco per farlo? Mi riferisco alla nuova funzionalità in C ++ 11


1
Tutto tranne i tipi fondamentali può essere assegnato a una variabile di tipo Object, quindi per alcune operazioni puoi usarlo Objectdove vuoi auto.
Zyx 2000,

1
nessun java non ha tale variabile
Aleksei Bulgak

@ Zyx2000: Quindi utilizzerà la to_stringfunzione dell'oggetto e non l'oggetto effettivo in questione, no?
Giochi Brainiac

2
@GamesBrainiac: No, userà la versione sovrascritta, se esiste.
Keppil

2
Il termine che stai cercando non è "auto", è "inferenza di tipo". Ci sono alcune domande sull'inferenza del tipo in Java, anche se si riferiscono principalmente a generici, quindi non sono sicuro di come trovare un duplicato ...

Risposte:


49

Risposta prima che la domanda fosse MODIFICATA :

No, non esiste un autotipo di variabile in Java. Lo stesso ciclo può essere ottenuto come:

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

Java ha variabili locali, il cui ambito è all'interno del blocco in cui sono state definite. Simile a C e C ++, ma non esiste una parola chiave auto o register. Tuttavia, il compilatore Java non consentirà l'uso di una variabile locale non inizializzata in modo esplicito e darà un errore di compilazione (a differenza di C e C ++ dove il compilatore di solito fornisce solo un avviso). Cortesia: Wikipedia .

No, non esiste alcuna inferenza di tipo mainstream in Java come C ++. C'era un RFE ma questo è stato chiuso come "Will not fix", il motivo fornito era:

Gli esseri umani beneficiano della ridondanza della dichiarazione del tipo in due modi. Primo, il tipo ridondante serve come documentazione preziosa: i lettori non devono cercare la dichiarazione di getMap () per scoprire quale tipo restituisce. In secondo luogo, la ridondanza consente al programmatore di dichiarare il tipo desiderato e quindi di beneficiare di un controllo incrociato eseguito dal compilatore.


10
@GamesBrainiac No, le chiamate ai metodi sono sempre polimorfiche in Java. Tuttavia, molte altre cose (ad esempio la risoluzione del sovraccarico o qualsiasi operazione non definita su Object) non possono essere eseguite in questo modo. Questa non è proprio una buona risposta, capita che funzioni solo perché l'esempio nella domanda è debole.

10
Questa domanda riguarda l'inferenza del tipo in C ++ 11, non il vecchio uso di autoC e pre-C ++ 11. La tua modifica è fuori tema.

4
"Non è quello che volevo dire, una volta che digiti cast it to a Object, ti darà to_string Object" False. Assolutamente falso al 100%.
Louis Wasserman

140
"Gli esseri umani traggono vantaggio dalla ridondanza". È vero. Ogni mattina mi sveglio e penso "come posso rendere il mio codice più ridondante?". A causa dei vantaggi.
ahoffer

2
Inoltre questa risposta è obsoleta perché varè una parola chiave riservata a partire da Java 9.
6infinity8

69

Potrebbe essere Java 10 ha ciò che tu (e io) vogliamo, attraverso la varparola chiave.

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

Dalle proposte di miglioramento JDK 286


Aggiornamento: Yap, quella funzione è arrivata nella versione Java 10!


6
È un miglioramento, ma quella parola chiave può funzionare solo con variabili locali. Non potente come l'inferenza del tipo automatico C ++
texasbruce

7
Piccola pignoleria: varnon è una parola chiave! Dal JLS : "var non è una parola chiave, ma piuttosto un identificatore con un significato speciale come il tipo di dichiarazione di una variabile locale". Quindi, a differenza delle parole chiave, non c'è nulla che ti impedisca di chiamare una variabile o un metodo "var".
Klitos Kyriacou

2
Buon punto @KlitosKyriacou. Tuttavia, se immagino di sostituire "parola chiave" con "identificatore" - o anche "identificatore con significato speciale come tipo di dichiarazione di una variabile locale" - la risposta sarebbe meno chiara, credo. Ma sì, in vareffetti non è nell'elenco delle parole chiave.
sorrymissjackson

Non è una parola chiave solo per compatibilità con le versioni precedenti. Oltre al fatto che puoi avere un identificatore con questo nome, var ha il ruolo di una parola chiave.
facetus

25

Java 7 introduce la sintassi del diamante

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

Rispetto al vecchio java

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

Il lettore critico noterà che questa nuova sintassi non aiuta a scrivere i cicli for nella domanda originale. Sembra corretto e del tutto intenzionale. Vedi l'altra risposta che cita il database dei bug di Oracle.


4
Vero, ma quello che lui (e io) stiamo cercando è qualcosa del tipo auto integerBox = new Box<Integer>();HashMap<String, LinkedList<Operation, Set<Integer>>>
:,

1
Questa preoccupazione è esattamente ciò che ho affrontato dopo gli esempi di codice. La conclusione è stata che Java non lo fa, e questo è apposta.
Tarrasch

18

In Java 8, puoi utilizzare l'inferenza del tipo lambda per evitare di dichiarare il tipo. L'analogo agli esempi dell'interrogante sarebbe:

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

entrambi possono anche essere semplificati utilizzando i riferimenti al metodo:

object_array.forEach(System.out::println); 
object_array.forEach(ObjectType::do_something_that_only_this_particular_obj_can_do);

8

In breve, no, non esiste il tipo di auto. Se tutto ciò che stai facendo è stampare il valore, potresti semplicemente fare riferimento al valore come un file Object.


o calcolare hashCodes, o raccogliere nomi di classi, o ... hai avuto l'idea;) L'elenco è breve, però. Vedi i documenti della classe Object (commento destinato ai principianti, sono sicuro che lo sapevi SimonC)
Alexander Malakhov

4

Non è una soluzione Java pura, tuttavia l'aggiunta di una libreria chiamata lombok consentirà alla magia di seguito di compilarsi e funzionare in modo molto simile alla autoparola chiave in C ++

List<String> strList = Arrays.asList("foo", "bar", "baz");
for (val s: strList){
    System.out.println(s.length());
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.