2011-01-27 15 views
7

Le classi interne sono più leggere delle normali classi o, alla fine, Java compila le classi interne come le normali classi?Le classi interne sono leggere?

So che le classi in Java non sono tutte molto leggere e occupano parte della memoria permgen, quindi mi piacerebbe sapere se è meglio usare le funzioni di chiusura come classi interne, o se le classi standard anche fare bene?

+1

La JVM ha solo tipi di dati primitivi ('int',' float', ecc.) E classi. Non c'è niente tra di loro. – Gabe

risposta

17

Le classi interne e le classi interne anonime si compilano entrambi nei file .class. Per esempio:

class Outer { 
    class Inner { 

    } 

    Object function() { 
      return new Object() { 

      }; 
    } 
} 

genererà tre .class file, Outer.class, Outer$Inner.class, e Outer$1.class. Non sono più "leggeri" di altre classi e (per quanto ne so io) non c'è alcun vantaggio nell'usare l'uno sull'altro dal punto di vista delle prestazioni. Naturalmente, le classi interne e le classi interne particolarmente anonime sono davvero utili in contesti in cui le classi regolari sono più difficili da codificare, ma questo è un problema separato.

+7

+1. Se le classi interne sono "più pesanti" perché contengono metodi e campi sintetici che il compilatore crea per facilitare le speciali regole di visibilità che hanno rispetto alla loro classe contenente. – Thilo

+0

Wow! Grazie per le informazioni! – Waneck

1

Non sono leggeri, ma hanno dei limiti. AFAIK, non puoi creare più di un'istanza di una classe interna anonima, quindi, se le tue esigenze lo richiedono, devi utilizzare una classe non anonima.

modifica 1: Grazie per tutti i commenti e chiarimenti. Per favore aiutami a capirlo meglio ... Capisco che puoi avere più istanze di classi interne anonime, ma se dichiaro un oggetto ActionListener interno anonimo per esempio, come posso avere più istanze di di quella classe e solo quella classe senza usare la riflessione? Grazie in anticipo (o dovrei chiedere questo nella mia stessa domanda?)!

OK, dal momento che non sto ricevendo alcun morso ... Fammi dimostrare con il codice. Dire che creo un ActionListener anonimo qui:

JButton button = new JButton("Button"); 

    button.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     System.out.println("Button says \"Foo!\""); 
    } 

    }); 

    JOptionPane.showMessageDialog(null, button); 

creo un ActionListener anonima e anche creare un oggetto di questa classe in un colpo solo. Quello che mi è sempre stato insegnato, quello che ho menzionato in cima al mio post qui (e mi sono fatto male per) è che è difficile se non impossibile (senza la magia della riflessione) fare un altro oggetto di questa classe anonima, che solo un oggetto può essere creato e in situazioni in cui è necessario un solo oggetto, questo è corretto. Ma in altre situazioni, non va bene. E certo, si potrebbe creare più classi ActionListener anonime simili, come in un ciclo for:

JPanel panel = new JPanel(new GridLayout(5, 5)); 
    JButton[] buttons = new JButton[25]; 
    for (int i = 0; i < 25; i++) { 
    final int btnNumber = i; 
    buttons[i] = new JButton(String.valueOf(btnNumber)); 
    buttons[i].addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("From button " + btnNumber); 
     } 
    }); 
    panel.add(buttons[i]); 
    } 
    JOptionPane.showMessageDialog(null, panel); 

Ma anche così, ogni classe anonima creato qui è diverso. Questo può avere un significato se questo stesso tipo di listener è usato da più JButtens, che ha uno stato, e il suo comportamento dipende da questo stato. Essere d'accordo? Disaccordo? Grazie in anticipo per qualsiasi input!

+3

È possibile avere più istanze di classi interne anonime, ad esempio, inserendo la classe in un ciclo 'for' e istanzandola più volte.Penso che Java richieda che tutte queste classi abbiano lo stesso tipo, ma non ricordo se è corretto o meno. – templatetypedef

+1

Ci stai pensando troppo. Una classe interiore anonima è ancora una classe. Puoi avere tutte le occorrenze a tuo piacimento. Puoi anche avere tutte le classi interne anonime che desideri vengano specificate. Il compilatore gestisce tutto questo in fase di compilazione. La prima specifica anonima che trova ottiene il bel nome di Foo $ 1, il secondo è Foo $ 2, e così via. Il codice come 'new Runnable() {...}' diventa 'Foo.new 1()'. –

+0

Grazie per i commenti e le informazioni utili! Per favore, chiarisci per me ... se ho un ActionListener interno anonimo, come posso avere due istanze distinte di questa classe (senza riflessione) poiché è creata mentre l'oggetto è creato. So che posso avere molte istanze di ActionListeners anonimi, ma mi chiedo come sia possibile avere più istanze di una classe anonima distinta che è stata dichiarata. –

7

Le classi interne sono ancora classi e devono ancora essere caricate da un ClassLoader. Se mai, è vero il contrario. Una classe interna non statica può mantenere la classe genitore dall'essere garbage collection poiché ha un riferimento alla classe che lo possiede.

+1

+1. Oltre al riferimento principale, esistono anche metodi sintetici per consentire di chiamare metodi "privati" dalle classi correlate. – Thilo

Problemi correlati