Soy muy consciente de que los tipos genéricos se borran del código de Java cuando se compila. ¿Qué información (atributos?) Usan 1.5+ JVM para implementar getGenericType
, etc.?¿Dónde se almacenan los tipos genéricos en archivos de clase java?
Respuesta
Se almacenan en los atributos Signature
; ver la sección 4.8.8 del updated Java Virtual Machine Specification, así como la sección 4.4.4 para el formato de la firma del tipo de campo.
Aquí hay un ejemplo usando javap -verbose java.util.Map
:
public interface java.util.Map
SourceFile: "Map.java"
Signature: length = 0x2
00 1E
[other attributes omitted]
El atributo Signature
aquí especifica (si lee esto como big-endian, como todas las cantidades de números enteros en el formato de archivo de clase JVM son) el valor de la piscina constante # 30 (30 = 0x1E).Así que echemos un vistazo allí:
const #30 = Asciz <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;;
Lea esto en el contexto de la gramática especificada en 4.4.4. Por lo tanto, esto utiliza dos parámetros de tipo, K extends java.lang.Object
y V extends java.lang.Object
. El tipo en sí (Map
) también extiende la clase java.lang.Object
, y no tiene interfaces.
Los genéricos de Java están efectivamente implementados por type erasure, por lo que no hay información de tipo en el bytecode.
Por ejemplo, vamos a echar un vistazo dos clases que declaran un campo List
, una en genérico y la otra en forma no genérico:
class NonGeneric {
List list;
}
Y,
class Generic {
List<String> list;
}
En ambos casos , el bytecode resultante es el siguiente:
Code:
Stack=3, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: new #2; //class java/util/ArrayList
8: dup
9: invokespecial #3; //Method java/util/ArrayList."<init>":()V
12: putfield #4; //Field list:Ljava/util/List;
15: return
No hay referencias ce al tipo String
utilizado en el ArrayList
o List
. Entonces, podemos ver que los genéricos se implementan por borrado de tipos.
Sin embargo, si miramos el conjunto constante, podemos encontrar una diferencia.
El no genérico del grupo de constantes:
Constant pool:
const #1 = Method #6.#15; // java/lang/Object."<init>":()V
const #2 = class #16; // java/util/ArrayList
const #3 = Method #2.#15; // java/util/ArrayList."<init>":()V
const #4 = Field #5.#17; // NonGeneric.list:Ljava/util/List;
const #5 = class #18; // NonGeneric
const #6 = class #19; // java/lang/Object
const #7 = Asciz list;
const #8 = Asciz Ljava/util/List;;
const #9 = Asciz <init>;
const #10 = Asciz ()V;
// snip the rest //
El genérico de memoria constante:
Constant pool:
const #1 = Method #6.#17; // java/lang/Object."<init>":()V
const #2 = class #18; // java/util/ArrayList
const #3 = Method #2.#17; // java/util/ArrayList."<init>":()V
const #4 = Field #5.#19; // Generic.list:Ljava/util/List;
const #5 = class #20; // Generic
const #6 = class #21; // java/lang/Object
const #7 = Asciz list;
const #8 = Asciz Ljava/util/List;;
const #9 = Asciz Signature;
const #10 = Asciz Ljava/util/List<Ljava/lang/String;>;;
const #11 = Asciz <init>;
const #12 = Asciz ()V;
// snip the rest//
Como puede verse, en la clase Generic
, podemos ver que hay dos constantes adicionales, #9
y #10
, en el grupo constante, que menciona que el List
tiene el tipo genérico String
.
(y la incorporación de nuevos conocimientos que he aprendido de Chris Jester-Young's answer)
Mirando más en el desmontaje del archivo de clase, hay una referencia a la constante # 10 justo antes de la Code: block
de la clase Generic
:
java.util.List list;
Signature: length = 0x2
00 0A
el valor hexadecimal 0A
es 10
en decimal, que se refiere a la piscina constante #10
:
const #10 = Asciz Ljava/util/List<Ljava/lang/String;>;;
Por lo tanto, la información del conjunto constante se utiliza para indicar que un campo es de tipo genérico.
- 1. ¿Dónde se almacenan los archivos evtx archivados?
- 2. ¿Dónde se almacenan los archivos de logcat de Android?
- 3. Dónde se almacenan los tipos de valores en (C#) Colecciones genéricas
- 4. ¿Dónde se almacenan los atributos de Java HttpSession?
- 5. ¿Dónde se almacenan los "Certificados" en Firefox?
- 6. ¿Dónde se almacenan los ivars sintetizados?
- 7. ¿Dónde se almacenan los módulos de python?
- 8. ¿Dónde se almacenan los paquetes del sistema Java?
- 9. ¿Dónde se almacenan las clases de Java en Oracle?
- 10. ¿Dónde se almacenan los archivos jar en caché para las aplicaciones Java Web Start/JNLP?
- 11. ¿Dónde se almacenan los objetos temporales?
- 12. ¿Dónde se almacenan los mensajes flash?
- 13. ¿Dónde se almacenan los metadatos del puntero?
- 14. ¿Dónde se almacenan los archivos de usuario de Chrome/Tampermonkey en el sistema de archivos?
- 15. ¿Dónde se almacenan las variables locales finales de Java?
- 16. ¿Cómo uso los tipos genéricos paramertizados en una clase interna?
- 17. ¿Dónde se almacenan los métodos en la memoria?
- 18. ¿Dónde puedo encontrar programáticamente dónde se almacenan los archivos de registro log4j?
- 19. ¿Dónde se almacenan las macros?
- 20. ¿Por qué los tipos de valores se almacenan en Stacks?
- 21. ¿Dónde se almacenan los bloques CMS estáticos de Magento?
- 22. Como llegar clase con tipos genéricos en Java
- 23. Java: genéricos aceptar sólo los tipos de enumeración
- 24. ¿Dónde se almacenan las imágenes dentro de los programas?
- 25. tipos primas y Genéricos - Java
- 26. iPhone: ¿Dónde se almacenan NSUserDefaults?
- 27. ¿No puede ser tan específico con los tipos de campos genéricos de Java como con los tipos de métodos genéricos?
- 28. genéricos de Java: ¿clase?
- 29. ¿Dónde se almacenan los volcados centrales en Mac?
- 30. ¿Dónde se almacenan los archivos de registro de la aplicación Tomcat en Elastic Beanstalk?