¿Cuál es el $ 1 en los nombres de archivo de la clase?

  C: \ Archivos de progtwig \ Java \ jdk1.6.0_05 \ CoreJava \ v1 \ v1ch2 \ WelcomeApplet> dir
  El volumen en la unidad C no tiene etiqueta.
  El número de serie del volumen es 2041-64E7

  Directorio de C: \ Archivos de progtwig \ 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 archivo (s) 1,984 bytes
                2 Dir (s) 2,557,210,624 bytes gratis

 C: \ Archivos de progtwig \ Java \ jdk1.6.0_05 \ CoreJava \ v1 \ v1ch2 \ WelcomeApplet> javac WelcomeApplet.java

 C: \ Archivos de progtwig \ Java \ jdk1.6.0_05 \ CoreJava \ v1 \ v1ch2 \ WelcomeApplet> dir
  El volumen en la unidad C no tiene etiqueta.
  El número de serie del volumen es 2041-64E7

  Directorio de C: \ Archivos de progtwig \ 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 archivo (s) 4,338 bytes
                2 Dir (s) 2,557,202,432 bytes gratis

 C: \ Archivos de progtwig \ Java \ jdk1.6.0_05 \ CoreJava \ v1 \ v1ch2 \ WelcomeApplet>

Aquí está el contenido de ese archivo 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:gary@thecornells.com")); 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(); } } }; } } 

Esos son los archivos .class que contienen las clases internas anónimas .

En su ejemplo WelcomeApplet.java contiene una clase de nivel superior (llamada WelcomeApplet ) y una clase interna anónima, que se almacenará en WelcomeApplet$1.class .

Tenga en cuenta que el nombre exacto de los archivos que contienen clases internas anónimas no está estandarizado y puede variar. Pero en la práctica aún no he visto ningún otro esquema distinto al descrito aquí.

Los cuerpos específicos del valor para una enum también son clases internas anónimas :

El cuerpo de clase opcional de una constante enum define implícitamente una statement de clase anónima ( §15.9.5 ) que amplía el tipo de enumeración que encierra inmediatamente.

Los $ 1 son clases internas anónimas que definió en su archivo WelcomeApplet.java .

por ejemplo comstackndo

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

daría como resultado que se Run.class , Run$1.class y Run$innerNamed.class

Estos se generan a partir de las clases anidadas internas y estáticas en el archivo WelcomeApplet.java por el comstackdor de java.

Ver también esta pregunta y respuesta similar .

Es a partir de esta ‘línea’ de código:

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

La forma en que declara el ActionListener está creando una instancia de la clase interna anónima cada vez que se invoca ese método.

Incluso si no se llama al método, la línea anterior aún se comstack en una clase interna anónima sin importar nada.

El archivo WelcomeApplet$1.class se genera para una clase anónima en la fuente WelcomeApplet.java (la clase anónima se genera en la llamada al método makeURLActionListener llamando al new new ActionListener() {...} )

Para explicarlo más claramente, las clases anónimas se generan en tiempo de comstackción siempre que tenga una creación de una clase concreta con nombre que anule parcial o totalmente el comportamiento de la clase concreta (o interfaz) en línea de esta manera:

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

En el código de ejemplo anterior, el comstackdor javac generará 2 archivos de clase como en su ejemplo: HelloInternalClass.class y HelloInternalClass$1.class .

La clase anónima en esta instancia sería una subclase de Runnable y se comstackría en HelloInternalClass$1.class . Dicho sea de paso, si solicita un nombre de clase de la instancia ejecutable en la muestra anterior (llamando a getClass().getName() ) encontrará que se considera a sí mismo como ” HelloInternalClass $ 1 “.

Crear:

 public class A { public static void main(String[] args) { X x=new X(); X x2=new X(){ }; Classc2=x2.getClass(); Classs2=x2.getClass().getSuperclass(); boolean b=false; } private static class X{ } } 

Es difícil de ver en el código (la new X{}() hubiera sido mejor que la new X(){} ), pero x2 es una instancia de una subclase de A$X Esta subclase es A$1 .