2011-01-23 7 views

risposta

6

solo sintassi, le cosiddette classi anonime sono classi normali al 100%. è possibile ottenere risultati funky usando java.lang.reflect.Proxy e InvocationHandler, sarebbe il modo più sporco per farlo.

modi più semplici includono dichiarando la classe nel metodo e solo l'aggiunta di 'strumenti',

classi
6

anonimi sono forniti come un modo per costruire in modo rapido e conciso una classe "una tantum". La tua domanda suggerisce che stai tentando di usare la tua anon class in diversi modi (almeno un'interfaccia e una estesa). In questo caso, sarebbe più leggibile e più mantenibile se si promuove quella classe anon a una classe completa.

Ciò eviterebbe anche effetti collaterali inaspettati, gestendo meglio l'incapsulamento delle classi.

6

Trovato un hack intorno a questo

creare un'interfaccia nella parte inferiore della vostra strega del file si estende tutte le interfacce che si desidera implementa quindi creare una classe anonima, di cui implementa questa.

+2

Non so che chiamerei questo un hack – Michael

23

C'è un problema interno per cui le classi java anonymous non possono implementare e sottoclasse contemporaneamente?

Credo che sia il 99% a causa di motivi sintattici. I parametri di tipo supportano anche intersection types (<T extends InterfaceX & InterfaceY>), quindi non penso che nel sistema di tipi si verifichino "contraddizioni" o addirittura complicazioni se il supporto per tale funzione verrà aggiunto.

Un'espressione come new (InterfaceX & InterfaceY)() { ... } potrebbe benissimo essere compilato in qualcosa di simile

interface InterfaceXandY extends InterfaceX, InterfaceY {} 

... new InterfaceXandY() { ... } 

Il motivo non v'è alcun supporto per esso è probabilmente dovuto al fatto che si tratta di un caso d'uso molto raro, che c'è una soluzione semplice.


Su una nota alquanto correlata. È possibile lasciare un lambda implementare per esempio Serializable facendo

Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!"); 

Vedere How to serialize a lambda?

+0

Ottima risposta +1. Assolutamente d 'accordo sul fatto che se esiste un banale work-around presente, perché fare un cambiamento fondamentale nella lingua e introdurre una sintassi macchinosa di due tipi statici. –

4

According to James Gossling:

chiusure sono stati lasciati fuori di Java inizialmente più a causa del tempo pressioni di qualsiasi altra cosa . Nei primi giorni di Java la mancanza delle chiusure era piuttosto dolorosa, e così nacquero classi interne: un compromesso scomodo che tentava di evitare un numero di problemi rigidi . Ma come è normale in così tanti problemi di progettazione, le semplificazioni non risolvono veramente alcun problema, semplicemente le spostano.

interessante, ora che le espressioni lambda e chiusure vengono aggiunti a Java, e questa volta strumentato con qualcosa di diverso rispetto a classi interne, potremmo definire un oggetto al volo composto da più di un'interfaccia, a condizione che il secondo uno è l'interfaccia marker.

interface Bar { 
    default String getName() { return "Bar"; } 
} 

Object o = (Comparable<Integer> & Bar) (x,y) -> x > y ? x : y; 
Bar b = (Bar) o; 
System.out.println(b.getName()); //Bar 

Questo compila e funziona perfettamente nel mio ultimo build del JDK 8 (12 marzo 2013). Quindi, sembrerebbe che stiano riflettendo maggiormente su questo problema.