2016-01-10 25 views
8

Java-8 consente di definire metodi statici all'interno dell'interfaccia, ma restricts esso invocazione soltanto nome dell'interfaccia:illegale metodo di interfaccia statico chiamata

9.4: An interface can declare static methods, which are invoked without reference to a particular object.

Es:

interface X { 
    static void y() { 
    } 
} 

... 

X x = new X() {}; 
x.y(); 

cause di errore:

error: illegal static interface method call 
     x.y(); 
      ^
    the receiver expression should be replaced with the type qualifier 'X' 

Spesso in JLS questo tipo di divieti hanno una spiegazione. In questo caso non ho trovato nulla di dettagliato. Quindi sto cercando una spiegazione completa o autorevole di questa regola: perché è vietato invocare il metodo statico tramite un particolare riferimento all'oggetto? Cosa si rompe?

+14

Forse la domanda migliore è il motivo per cui i metodi statici possono essere richiamati sui riferimenti oggetto in primo luogo ... –

+1

In questa nota, come si ottiene un'istanza di un'interfaccia X nella riga sopra? – aiguy

+2

totalmente d'accordo con @SkinnyJ Penso che gli sviluppatori Java stanno cercando di correggere il loro errore che hanno fatto rendendo disponibile l'oggetto statico per oggetto che è un po 'confuso – silentprogrammer

risposta

16

È un consenso abbastanza forte che la sintassi in questione non dovrebbe essere consentita per i metodi statici sulle classi, ma al momento in cui è stato realizzato era troppo tardi per cambiare. Non era troppo tardi per i metodi di interfaccia aggiunti di recente.

Inoltre, consentendo questa sintassi introdurrebbe la possibilità del problema del diamante, in quanto una classe potrebbe implementare interfacce che definiscono metodi di collisione.

+8

Questa analisi è corretta. Consideriamo la possibilità di invocare un metodo statico attraverso un'istanza per essere un errore di progettazione della lingua, sfortunatamente quello che non possiamo correggere retroattivamente per le classi. Potremmo almeno non commettere lo stesso errore. (A volte scegliamo deliberatamente di "fare lo stesso errore" quando estendiamo la lingua, scegliendo la coerenza rispetto al miglioramento locale - ma la scelta implica un giudizio di "bene, quanto è migliore il miglioramento?" Qui la differenza era grande –

+1

@Brian Goetz: ... e potrebbe rompere il codice esistente (una volta ricompilato), se un nuovo metodo di interfaccia 'static' risulta essere più specifico del metodo di istanza precedentemente richiamato. Suppongo che questo sia anche (uno dei) motivi per non ereditare i metodi di interfaccia 'static'. L'evoluzione delle interfacce dovrebbe avere il minor impatto possibile sulle implementazioni esistenti. – Holger

+1

@Holger ... e inoltre, l'introduzione di valori predefiniti e di statica ereditabile allo stesso tempo avrebbe causato ancora più confusione. Molte ragioni per tracciare questa linea qui. –