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.