2012-03-01 13 views
16

Ho visto l'evento virtuale Oracle OTN: Java SE e JavaFX 2.0 (28 febbraio 2012) e mentre parlavo del nuovo operatore di diamanti (quello Map<String, List<String>> myMap = new HashMap<>();), l'oratore ha affermato che non era come un semplice strumento di quello che si potrebbe pensare, poiché non è una semplice sostituzione di token.Java 7 diamond operator: perché è stato difficile implementarlo?

La mia domanda è perché? Perché non è possibile implementarlo semplicemente prendendo la stringa dalla dichiarazione della variabile e inserendola nell'operatore del diamante?

+3

In aumento. Perché abbiamo persino bisogno di un operatore per questo? – Croo

risposta

14

Non l'ho nemmeno implementato, quindi posso solo indovinare.

Ma di solito il motivo per cui queste cose sono più complesse di quanto sembrino è che la prima ispezione guarda solo al caso d'uso più comune (o più pubblicizzato). In questo caso è quello che hai menzionato. In teoria dovrebbe essere facile da specificare esattamente e dovrebbe essere piuttosto facile da implementare in un compilatore.

Tuttavia, l'operatore diamante (che non è tecnicamente un operatore, tra l'altro) può essere utilizzato in modi diversi, come pure:

someMethodWithGenericArguments(new HashMap<>()); 
new SomeGenericClass(new HashMap<>()); 
T foo = new SomethingRelatedToT<>(); // where T is a generic type parameter 

In questi casi una semplice sostituzione gettone ovviamente non funziona più, è bisogno di inferenza di tipo reale che coinvolge analisi di tipo reale (cioè è su un livello di astrazione completamente diverso come sarebbe una semplice sostituzione di token).

+0

Grazie, vedo che queste sono situazioni molto più complesse. Il primo caso solleva la questione che cosa succede se 'someMethodWithGenericArguments()' è sovraccarico di ˙Map ˙ e 'Map ' .. In questo caso il diamante op. sembra totalmente ambiguo per me .. – jabal

+0

@jabal: provalo! Poiché 'Map ' e 'Map ' hanno la stessa cancellazione ('Map') non è possibile avere questi due override di un singolo metodo. –

2

Qualcosa che Java non fa (che molte lingue hanno) è tipi impliciti basati sull'uso. Ad esempio, Java non implica un tipo di richiesta in base a come viene utilizzato.

ad es.

Type a = b; 

Il tipo di a e il tipo di b sono indipendenti e non effettua stime circa b base al tipo di a.

MethodHandles sta mostrando segni di supporto. L'utilizzo del tipo di reso può essere basato sul contesto, ma questa è una funzione di runtime.

In conclusione, la mia ipotesi è; Era difficile da implementare in Java perché il linguaggio non supportava niente del genere. Se la lingua utilizzata ha sempre una funzione come questa, l'approccio da adottare sarebbe compreso (in termini di definizione di una specifica di come dovrebbe funzionare) e supportato dagli strumenti nel compilatore.

+3

Stranamente, il compilatore * già * supporta l'inferenza di tipo per gli argomenti di tipo generico di * method calls *. Ma per * istanziazione di oggetti * questa funzione è stata aggiunta solo con l'operatore Diamond. –

Problemi correlati