Sono ben consapevole del fatto che i tipi generici vengono cancellati dal codice Java quando viene compilato. Quali informazioni (attributi?) Utilizzano 1.500 JVM per implementare getGenericType
, ecc.?Dove sono memorizzati i tipi generici nei file di classe java?
risposta
Sono memorizzati negli attributi Signature
; vedere la sezione 4.8.8 di updated Java Virtual Machine Specification, nonché la sezione 4.4.4 per il formato della firma del tipo di campo.
Ecco un esempio utilizzando javap -verbose java.util.Map
:
public interface java.util.Map
SourceFile: "Map.java"
Signature: length = 0x2
00 1E
[other attributes omitted]
L'attributo Signature
qui specifica (se leggi questo come big-endian, come tutte le quantità interi nel formato di file di classe JVM sono) piscina costante valore # 30 (30 = 0x1E).Diamo un'occhiata:
const #30 = Asciz <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;;
Leggere nel contesto della grammatica specificata in 4.4.4. Quindi, utilizza due parametri di tipo, K extends java.lang.Object
e V extends java.lang.Object
. Il tipo stesso (Map
) estende anche la classe java.lang.Object
e nessuna interfaccia.
I generici Java sono effettivamente implementati da type erasure, quindi non ci sono informazioni sul tipo nel bytecode.
Per esempio, diamo uno sguardo due classi che dichiarano un campo List
, uno nel generico e l'altro in forma non generica:
class NonGeneric {
List list;
}
E,
class Generic {
List<String> list;
}
In entrambi i casi , il bytecode risultante è il seguente:
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
Non vi è alcun riferimento ce al tipo String
utilizzato nel ArrayList
né List
. Quindi, possiamo vedere che i farmaci generici sono effettivamente implementati dalla cancellazione dei tipi.
Tuttavia, se guardiamo al pool costante, possiamo trovare una differenza.
Il non generico piscina costante:
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 //
La generica piscina costante:
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//
Come si può vedere, nella classe Generic
, possiamo vedere ci sono due costanti in più, #9
e #10
, nel pool costante, che indica che il List
ha il tipo generico di String
.
(e incorporando nuove conoscenze che ho imparato da Chris Jester-Young's answer)
Guardando più al smontaggio del file di classe, c'è un riferimento alla costante # 10 a destra prima del Code: block
della classe Generic
:
java.util.List list;
Signature: length = 0x2
00 0A
il valore esadecimale 0A
è 10
in decimale, che si riferisce alla piscina costante #10
:
const #10 = Asciz Ljava/util/List<Ljava/lang/String;>;;
Pertanto, le informazioni del pool costante vengono utilizzate per indicare che un campo è di tipo generico.
- 1. Dove sono memorizzati i tipi nullable in memoria?
- 2. Dove sono memorizzati i segnalibri Eclipse?
- 3. Dove sono memorizzati i dati di stringa?
- 4. Dove sono memorizzati i messaggi flash?
- 5. Dove sono memorizzati i metodi in memoria?
- 6. Dove sono memorizzati i cookie di UIWebView?
- 7. Android: dove sono memorizzati i file di database?
- 8. Dove sono memorizzati i rami Git?
- 9. Dove sono memorizzati i certificati SSL?
- 10. Dove i cookie sono memorizzati nel sistema?
- 11. Dove sono memorizzati i "certificati" in Firefox?
- 12. Dove sono memorizzati i server registrati?
- 13. Anche i tipi di valore nell'oggetto sono memorizzati nell'heap?
- 14. Devo evitare i tipi annidati nei tipi generici?
- 15. opzioni SET .... dove sono memorizzati
- 16. Dove sono i riferimenti di componenti (dll) memorizzati in ASP.NET?
- 17. Dove sono memorizzati i blocchi CMS statici di Magento?
- 18. Dove sono memorizzati i file jar per le applicazioni Java Web Start/JNLP?
- 19. Dove posso trovare in modo programmatico dove sono memorizzati i file di log log4j?
- 20. Sessioni di flaconi, dove sono memorizzati i cookie?
- 21. Dove sono archiviati i tipi di valore in (C#) Raccolte generiche
- 22. Dove sono memorizzati i riferimenti all'assembly del progetto dell'applicazione Web?
- 23. Dove sono memorizzati i drawable o clipart da android.R.drawable?
- 24. Come confrontare i tipi generici?
- 25. Tipo controllo di una classe con i tipi generici
- 26. tipi Java generici errore di mancata corrispondenza
- 27. Come si risolvono i metodi ambigui causati dai tipi di intersezione nei generici Java?
- 28. Dove sono memorizzati gli oggetti temporanei?
- 29. Come, quando e dove i metodi generici sono resi concreti?
- 30. Contenitore di tipi generici in java