È possibile rendere anonima interna classi in Java statico?
-
09-09-2019 - |
Domanda
In Java le classi nidificate può essere static
o non.Se sono static
, non contengono un riferimento al puntatore del contenente istanza (che non sono, inoltre, chiamati classi interne più, essi sono chiamati classi nidificate).
Dimenticare di fare una classe nidificata static
quando non ha bisogno che di riferimento può portare a problemi con la spazzatura raccolta di fuga o di analisi.
È possibile fare un anonymous inner class static
come bene?O fa il compilatore a capire questo fuori automaticamente (che potrebbe, in quanto non ci può essere alcuna delle sottoclassi)?
Per esempio, se faccio un anonimo comparatore, non ho quasi mai necessario il riferimento per l'esterno:
Collections.sort(list, new Comparator<String>(){
int compare(String a, String b){
return a.toUpperCase().compareTo(b.toUpperCase());
}
}
Soluzione
No, non è possibile, e no, il compilatore non può capire.Questo è il motivo per cui FindBugs sempre suggerisce di cambiare anonymous inner class a static
classi nidificate, anche se non usano la loro implicita this
di riferimento.
Edit: Tom Hawtin - tackline dice che, se l'anonimo classe viene creata in un contesto statico (es.nel main
il metodo), la classe anonima è infatti static
.Ma il JLS non è d'accordo:
Una classe anonima non è mai
abstract
(§8.1.1.1).Una classe anonima è sempre una classe interna (§8.1.3);non è maistatic
(§8.1.1, §8.5.1).Una classe anonima è sempre implicitamentefinal
(§8.1.1.2).
Roedy Verde Java Glossario dice che il fatto che anonymous lezioni sono ammessi in un contesto statico è dipendente dall'implementazione:
Se si desidera deflettore quelli manutenzione del codice, si agita hanno scoperto
javac.exe
permetterà anonimo classi all'interno distatic
codice di inizializzazione estatic
metodi, anche se la lingua spec dice di anonimo classi non sono maistatic
.Questi anonimi classi, naturalmente, non hanno accesso ai campi di istanza dell'oggetto.Io non consiglio di fare questo.Il funzione potrebbe essere tirato in qualsiasi momento.
Edit 2: I JLS in realtà copre statico contesti più esplicitamente §15.9.2:
Lasciate C classe istanziato, e lasciare che io essere l'istanza creata.Se C è una classe interna quindi io può immediatamente allegando istanza.Immediatamente allegando istanza di io (§8.1.3) è determinato come segue.
- Se C è una classe anonima, quindi:
- Se l'istanza della classe la creazione di espressione si verifica in un contesto statico (§8.1.3), quindi io non ha subito allegando istanza.
- In caso contrario, immediatamente allegando istanza di io è
this
.
Così una classe anonima in un contesto statico è approssimativamente equivalente a un static
classe nidificata in quanto non di mantenere un riferimento al allegando la classe, anche se è tecnicamente non un static
classe.
Altri suggerimenti
Una specie. Una classe interna anonima creata in un metodo statico sarà ovviamente in modo efficace statico perché non v'è alcuna fonte di un esterno questo.
Ci sono alcune differenze tecniche tra le classi interne in contesti statici e classi annidate statiche. Se siete interessati, leggere il JLS 3rd Ed.
Credo che ci sia un po 'di confusione nella nomenclatura qui, che devo ammettere che è troppo stupido e confusa.
Qualunque cosa tu li chiami, questi schemi (e un paio di varianti con diversa visibilità) sono tutto il possibile, normale, Java legale:
public class MyClass {
class MyClassInside {
}
}
public class MyClass {
public static class MyClassInside {
}
}
public class MyClass {
public void method() {
JComponent jc = new JComponent() {
...
}
}
}
public class MyClass {
public static void myStaticMethod() {
JComponent jc = new JComponent() {
...
}
}
}
Si sono soddisfatti nella specifica lingua (se sei davvero infastidito, vedere la sezione 15.9.5.1 per l'uno all'interno del metodo statico).
Ma questa citazione è semplicemente sbagliato :
javac.exe permetterà anonima all'interno delle classi codice init statico e metodi statici, anche se la lingua specifiche dice di anonimo le classi non sono mai statiche
Credo che l'autore citato confonde il static parola chiave con statico di contesto . (È vero che la JLS è anche un po 'di confusione al riguardo.)
Onestamente, tutti i modelli di cui sopra vanno bene (come si chiamano loro "annidata", "interno", "anonimo" qualunque cosa ...). In realtà, nessuno sta per rimuovere improvvisamente questa funzionalità nella prossima versione di Java. Onestamente!
Le classi interne non può essere statica - una classe innestata statica non è una classe interna. Java del tutorial ne parla qui .
classi interne anonime non sono mai statiche (non possono dichiarare metodi statici o campi statici non finale), ma se sono definiti in un contesto statico (metodo statico o campo statico) si comportano come statica, nel senso che essi non può accedere non statico (cioè esempio) membri della classe contenitrice (come tutto il resto da un contesto statico)
Sulla nota di fare una classe interna anonima statica chiamando loro all'interno di un metodo statico.
Questo in realtà non rimuovere il riferimento. È possibile verificare questo, cercando di serializzare la classe anonima e non fare della classe contenitrice serializzabile.