2009-07-02 9 views
35
C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet>dir 
Volume in drive C has no label. 
Volume Serial Number is 2041-64E7 

Directory of C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet 

2009-07-02 23:54    . 
2009-07-02 23:54    .. 
2004-09-06 14:57    582 WelcomeApplet.html 
2004-09-06 15:04    1,402 WelcomeApplet.java 
       2 File(s)   1,984 bytes 
       2 Dir(s) 2,557,210,624 bytes free 

C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet>javac WelcomeApplet.java 

C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet>dir 
Volume in drive C has no label. 
Volume Serial Number is 2041-64E7 

Directory of C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet 

2009-07-02 23:54    . 
2009-07-02 23:54    .. 
2009-07-02 23:54    975 WelcomeApplet$1.class 
2009-07-02 23:54    1,379 WelcomeApplet.class 
2004-09-06 14:57    582 WelcomeApplet.html 
2004-09-06 15:04    1,402 WelcomeApplet.java 
       4 File(s)   4,338 bytes 
       2 Dir(s) 2,557,202,432 bytes free 

C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet> 

Ecco il contenuto di tale file Java:

/** 
    @version 1.21 2002-06-19 
    @author Cay Horstmann 
*/ 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.net.*; 

public class WelcomeApplet extends JApplet 
{ 
    public void init() 
    { 
     setLayout(new BorderLayout()); 

     JLabel label = new JLabel(getParameter("greeting"), SwingConstants.CENTER); 
     label.setFont(new Font("Serif", Font.BOLD, 18)); 
     add(label, BorderLayout.CENTER); 

     JPanel panel = new JPanel(); 

     JButton cayButton = new JButton("Cay Horstmann"); 
     cayButton.addActionListener(makeURLActionListener(
     "http://www.horstmann.com")); 
     panel.add(cayButton); 

     JButton garyButton = new JButton("Gary Cornell"); 
     garyButton.addActionListener(makeURLActionListener(
     "mailto:[email protected]")); 
     panel.add(garyButton); 

     add(panel, BorderLayout.SOUTH); 
    } 

    private ActionListener makeURLActionListener(final String u) 
    { 
     return new 
     ActionListener() 
     { 
      public void actionPerformed(ActionEvent event) 
      { 
       try 
       { 
        getAppletContext().showDocument(new URL(u)); 
       } 
       catch(MalformedURLException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     }; 
    } 
} 

risposta

22

$ 1 sono classi interne anonime definiti nel file WelcomeApplet.java.

ad es. compilazione

public class Run { 
    public static void main(String[] args) { 
     System.out.println(new Object() { 
      public String toString() { 
       return "77"; 
      } 
     }); 
    } 
    private class innerNamed { 
    } 
} 

si tradurrebbe in Run.class, Run$1.class e Run$innerNamed.class viene generato

+0

Ma non c'è una classe interna in WelcomeApplet.java file.let mi aggiorna con il contenuto del file. – omg

+2

Sì, c'è. Viene avviato in questo modo: return new ActionListener() {public void actionPerformed ... –

+0

C'è una classe interna nell'applet ActionListener che si crea in makeURLActionListener() - Metod è una definizione inline di una classe. Si dice nuovo ActionListener() seguito dalla definizione della classe in {...} dove si implementa il metodo actionPerformed – jitter

46

Questi sono i file che contengono il .classanonymous inner classes.

Nel tuo esempio WelcomeApplet.java contiene una classe di primo livello (chiamato WelcomeApplet) e una classe interna anonima, che sarà memorizzato in WelcomeApplet$1.class.

Si noti che il nome esatto dei file contenenti classi interne anonime non è standardizzato e potrebbe variare. Ma in pratica non ho ancora visto nessun altro schema oltre a quello descritto qui.

corpi specifico valore per un enumare also anonymous inner classes:

Il corpo della classe facoltativa di un costante enum definisce implicitamente una dichiarazione classe anonima (§15.9.5) che si estende tipo enum immediatamente racchiude.

+0

Ho incollato l'origine qui, e non esiste una classe interna anonima – omg

+0

@Shore: Sì, c'è. Sai cos'è una classe interiore anonima? –

+4

Esiste una classe anonima: la nuova ActionListener() {...} creerà una sottoclasse anonima di ActionListener –

3

Questi vengono generati dalle classi nidificate interne e statiche nel file WelcomeApplet.java dal compilatore java.

Vedere anche questo similar question and answer.

+0

Ma non c'è nessuna classe interna anonima nella sorgente per tutti – omg

+0

Naturalmente, in makeURLActionListener() si sta generando una classe interna anonima per ActionListener. Questa è l'origine :) – Kosi2801

2

E 'da questa 'linea' di codice:

return new 
    ActionListener() 
    { 
     public void actionPerformed(ActionEvent event) 
     { 
      try 
      { 
       getAppletContext().showDocument(new URL(u)); 
      } 
      catch(MalformedURLException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    }; 

Il modo in cui si dichiara la ActionListener si stanno facendo un'istanza della classe interna anonima ogni volta che viene chiamato il metodo.

Anche se il metodo non viene chiamato, la riga precedente viene comunque compilata in una classe interna anonima, a prescindere da cosa.

+0

Cosa succede se non viene chiamato? Verrà generato '$ 1.class'? – omg

+0

sì. quella classe è generata non importa quale. tuttavia non avrai mai istanze di quegli oggetti. – jjnguy

1

Il file WelcomeApplet$1.class viene generato per una classe anonima nella fonte WelcomeApplet.java (la classe anonima viene generato nella makeURLActionListener chiamata di metodo chiamando new new ActionListener() {...})

per spiegare più chiaramente, le classi anonime vengono generate in fase di compilazione volta ogni volta che avete un'istanza di una concreta nome classe che sostituisce alcuni o tutti il ​​comportamento della classe concreta (o interfaccia) in linea in questo modo:

class HelloInternalClass { 
    public static final void main(String[] args) { 
    // print in another thread 
    new Thread(new Runnable() { 
     public void run() { 
     System.out.println("Printed from another thread"); 
     } 
    }).start(); 
    } 
} 

Nel codice di esempio sopra, il compilatore javac genererebbe 2 file di classe come nel tuo esempio: HelloInternalClass.class e HelloInternalClass$1.class.

La classe anonima in questo caso sarebbe una sottoclasse di Runnable e verrà compilata in HelloInternalClass$1.class. Per inciso, se si chiedesse un nome di classe dall'istanza eseguibile nell'esempio precedente (chiamando lo getClass().getName()) si troverà che pensa a se stesso come "HelloInternalClass $ 1".

0

Crea:

public class A { 
    public static void main(String[] args) { 
     X x=new X(); 
     X x2=new X(){ 
     }; 
     Class<? extends Object>c2=x2.getClass(); 
     Class<? extends Object>s2=x2.getClass().getSuperclass(); 

     boolean b=false; 
    } 
    private static class X{  
    } 
} 

E 'difficile vedere dal codice (new X{}() sarebbe stato meglio di new X(){}), ma x2 è un'istanza di una sottoclasse di A$X. Questa sottoclasse è A$1.

Problemi correlati