las clases compiladas de Java contienen signos de dólar

83

He estado usando Eclipse como mi IDE de desarrollo. También lo uso para exportar mi aplicación a un archivo .jar. Cuando miro mis clases en el archivo .jar, algunas de mis clases contienen el nombre de esa clase, un signo de dólar y luego un número. Ejemplo:

  • Encuentra $ 1.clase
  • Encuentra $ 2.clase
  • Encuentra $ 3.clase
  • Find.class

He notado que hace esto en clases más grandes. ¿Es esto porque las clases se vuelven tan grandes que las compila en múltiples clases? Busqué en Google y busqué en varios foros, y busqué la documentación de Java, pero no encontré nada relacionado con ella. ¿Alguien podría explicarlo?

Frizinator
fuente
Código de muestra para probar este problema github.com/Aksi0m/SampleFor123686419
Prags
Según la respuesta del equipo de Google issuetracker.google.com/issues/123736741 , esto se corrigió internamente y estará disponible en la próxima versión de Navigation.
Prags

Respuestas:

111

Las clases internas, si hay alguna presente en su clase, serán compiladas y el archivo de clases será ClassName$InnerClassName. En el caso de clases internas anónimas, aparecerá como números. El tamaño de la clase (código Java) no conduce a la generación de varias clases.

Por ejemplo, dado este fragmento de código:

public class TestInnerOuterClass {
    class TestInnerChild{

    }

    Serializable annoymousTest = new Serializable() {
    };
}

Las clases que se generarán serán:

  1. TestInnerOuterClass.class
  2. TestInnerOuterClass$TestInnerChild.class
  3. TestInnerOuterCasss$1.class

Actualizar:

El uso de clases anónimas no se considera una mala práctica, solo depende del uso.

Consulte esta discusión sobre SO

mprabhat
fuente
1
Bien, ¿es malo tener una clase anónima? No entiendo muy bien cómo funciona. Si creo una nueva variable de instancia de una clase en una clase, ¿es una clase anónima?
Frizinator
No, no está mal tener una clase anónima, depende del uso.
Actualicé
4
Las enumeraciones que contienen un cuerpo de clase generarán automáticamente una clase interna anónima que extiende la clase de enumeración y, por lo tanto, generarán otro archivo de clase con un $ en él.
dlaidlaw
1
Además, si la clase interna es privada, se genera una clase adicional denominada OuterClass $ 1.class
SandeepGodara
@mprabhat: ¿hay algún mecanismo en Android Studio para ver la jerarquía o lista de estas clases?
user1090751
15

Esto se debe a que tiene clases anónimas dentro de esta clase más grande. Se compilan utilizando esta convención de nomenclatura.

Ver el dilema de la clase anónima

jjathman
fuente
9

Además de los casos anteriores presentados por @mprabhat, los otros casos podrían ser:

  1. si su clase contiene una variable de enumeración , también se generará una clase separada para eso. El nombre de la .class generada sería ClassName $ Name_of_enum .
  2. Si su clase X está heredando, es decir, extendiendo otra clase Y , entonces se generaría una .class con el nombre ClassName $ 1.class o ClassName $ 1 $ 1.class
  3. Si su clase X está implementando una interfaz Y , entonces se generaría una .class con el nombre ClassName $ 1.class o ClassName $ 1 $ 1.class .

Estos casos son derivaciones de mi inspección en archivos .class en jar.

SGuru
fuente
Tengo una clase que no cumple ninguno de estos criterios, y class.getName () todavía es incorrecto; para Group.java, devuelve Group _ $$ _ jvst248_20. No tengo idea de lo que está pasando. Definitivamente no hay enumeraciones, extensiones o implementaciones.
Amalgovinus
0

Para responder a tu comentario sobre clases anónimas son malas. Definitivamente no lo son. Considere esto para asignar un oyente de acción a un JButton:

JButton button = new JButton(...);
button.addActionListener(new ActionListener() { ... });

o esto para hacer una ordenación insensible a mayúsculas y minúsculas por la propiedad "nombre"

Collections.sort( array, new Comparator<Foo>() {
    public int compare(Foo f1, Foo f2) {
        return f1.getName().toLowerCase().compareTo(f2.getName().toLowerCase());
    }
});

También verá una gran cantidad de Runnable y Callable realizadas como clases anónimas.

Mate
fuente