2009-07-02 6 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> 

ist der Inhalt dieser Java-Datei:

/** 
    @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(); 
       } 
      } 
     }; 
    } 
} 

Antwort

22

Die $ 1 die anonyme innere Klassen, die Sie in Ihrer WelcomeApplet.java-Datei definiert.

z.B.

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

kompilieren würde in Run.class, Run$1.class und Run$innerNamed.class

+0

Aber es gibt keine innere Klasse in WelcomeApplet.java file.let mich mit dem Dateiinhalt aktualisieren. – omg

+2

Ja, da ist. Es beginnt wie folgt: return new ActionListener() {public void actionPerformed ... –

+0

Es gibt eine innere Klasse in Ihrem Applet den ActionListener, den Sie in makeURLActionListener() erstellen - Metod ist eine Inline-Definition einer Klasse. Sie sagen neue ActionListener(), gefolgt von der Klassendefinition in {...}, wo Sie actionPerformed-Methode implementieren – jitter

46

Diejenigen erzeugt werden sind die .class Dateien, die die anonymous inner classes halten. In Ihrem Beispiel enthält WelcomeApplet.java eine Klasse der obersten Ebene (WelcomeApplet) und eine anonyme innere Klasse, die in WelcomeApplet$1.class gespeichert wird

Beachten Sie, dass der genaue Name der Dateien, die anonyme innere Klassen enthalten, nicht standardisiert ist und variieren kann. Aber in der Praxis habe ich noch kein anderes Schema als das hier beschriebene gesehen.

Wert spezifische Körper für eine enumare also anonymous inner classes:

Die optionale Klasse Körper einer Enum-Konstante definiert implizit eine anonyme Klassendeklaration (§15.9.5), der die unmittelbar umschließenden Aufzählungstyp erstreckt.

+0

Ich habe die Quelle hier einfügen, und es gibt keine anonyme innere Klasse – omg

+0

@Shore: Ja, es gibt. Weißt du was eine anonyme innere Klasse ist? –

+4

Es gibt eine anonyme Klasse: new ActionListener() {...} erstellt eine anonyme Unterklasse von ActionListener –

3

Diese werden aus den inneren und statischen geschachtelten Klassen in der WelcomeApplet.java-Datei vom Java-Compiler generiert.

Siehe auch diese similar question and answer.

+0

Aber es gibt überhaupt keine solche anonyme innere Klasse in der Quelle – omg

+0

Natürlich erzeugen Sie in makeURLActionListener() eine anonyme innere Klasse für den ActionListener. Das ist der Ursprung :) – Kosi2801

2

Aus dieser ‚Linie‘ des Codes ist:

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

Die Art und Weise erklären Sie, die ActionListener Sie machen eine Instanz der anonymen inneren Klasse jedes Mal, wenn Methode aufgerufen wird.

Auch wenn die Methode nicht aufgerufen wird, wird die obige Zeile immer noch in eine anonyme innere Klasse kompiliert, egal was passiert.

+0

Was, wenn es nicht heißt, wird '$ 1.class' generiert? – omg

+0

ja. Diese Klasse wird generiert, egal was passiert. Sie werden jedoch nie Instanzen dieser Objekte haben. – jjnguy

1

Die WelcomeApplet$1.class-Datei für eine anonyme Klasse in der WelcomeApplet.java Quelle erzeugt wird (die anonyme Klasse wird durch den Aufruf new new ActionListener() {...} in dem Methodenaufruf makeURLActionListener generiert)

deutlicher zu erklären, werden die anonymen Klassen während der Kompilierung erzeugt Zeit jedes Mal, wenn eine Instanz einer konkreten Namen Klasse, die einige oder alle das Verhalten der konkreten Klasse überschreibt (oder Schnittstelle) inline wie folgt aus:

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(); 
    } 
} 

In dem obigen Beispielcode würde der javac-Compiler generieren 2 Klassen-Dateien wie in Ihrem Beispiel: HelloInternalClass.class und HelloInternalClass$1.class.

Die anonyme Klasse in diesem Fall wäre eine Unterklasse von Runnable und würde in HelloInternalClass$1.class kompiliert werden. Wenn Sie im obigen Beispiel einen Klassennamen von der runnable-Instanz anfordern würden (indem Sie getClass().getName() aufrufen), würden Sie feststellen, dass er sich selbst als "HelloInternalClass $ 1" betrachtet.

0

erstellen:

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{  
    } 
} 

Es ist schwer, aus dem Code zu sehen (new X{}() hätte als new X(){} besser gewesen), aber x2 ist eine Instanz einer Unterklasse von A$X. Diese Unterklasse ist A$1.

Verwandte Themen