Mam świadomość, że typy ogólne są usuwane z kodu Java podczas kompilacji. Jakie informacje (atrybuty?) Są używane przez ponad 1.5 maszyn JVM do implementacji getGenericType
itd.?Gdzie są przechowywane typy ogólne w plikach klas java?
Odpowiedz
Są przechowywane w atrybutach Signature
; patrz sekcja 4.8.8 z updated Java Virtual Machine Specification, a także sekcja 4.4.4 dla formatu podpisu typu pola.
Oto przykład przy użyciu javap -verbose java.util.Map
:
public interface java.util.Map
SourceFile: "Map.java"
Signature: length = 0x2
00 1E
[other attributes omitted]
Atrybut tutaj określa (jeśli czytasz to jako grubokońcej, podobnie jak wszystkie ilości całkowitą w formacie klasy JVM ARE) stała pula wartość # 30 (Signature
30 = 0x1E).Zobaczmy więc:
const #30 = Asciz <K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;;
Przeczytaj to w kontekście gramatyki określonej w 4.4.4. Wykorzystuje to dwa parametry: K extends java.lang.Object
i V extends java.lang.Object
. Sam typ (Map
) również rozszerza klasę java.lang.Object
i nie zawiera żadnych interfejsów.
Generics Java są rzeczywiście realizowane przez type erasure, więc nie ma informacji o typie w bajtode.
Na przykład, weźmy spojrzeć dwie klasy, które deklarują List
pole, jeden w generycznym, a drugi w formie non-Generic:
class NonGeneric {
List list;
}
I
class Generic {
List<String> list;
}
W obu przypadkach , wynikowy kod jest następujący:
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
Brak informacji o typie String
używanym w ArrayList
ani List
. Widzimy więc, że generics jest rzeczywiście realizowany przez typ wymazania.
Jednakże, jeśli spojrzymy na stałą pulę, możemy znaleźć różnicę.
Non-generic stała pula:
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 //
Ogólny stały basen:
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//
Jak widać, w klasie Generic
widzimy, istnieją dwa dodatkowe stałe, #9
i #10
, w puli stałej, która mówi, że List
ma ogólny typ String
.
(i włączenie nowej wiedzy, że dowiedziałem się od Chris Jester-Young's answer)
Patrząc dalej w demontażu pliku klasy, nie ma odniesienia do stałej nr 10 tuż przed Code: block
klasy Generic
:
java.util.List list;
Signature: length = 0x2
00 0A
szesnastkowa 0A
jest 10
w układzie dziesiętnym, które odnosi się do puli stałej #10
:
const #10 = Asciz Ljava/util/List<Ljava/lang/String;>;;
Dlatego informacje z puli stałej są używane w celu wskazania, że pole ma typ ogólny.
- 1. Gdzie są przechowywane pakiety systemowe Java?
- 2. Gdzie są przechowywane makra?
- 3. Java - typy ogólne i kolekcje
- 4. Gdzie przechowywane są zmienne ulotne?
- 5. Gdzie przechowywane są dane const?
- 6. gdzie przechowywane są rozszerzone atrybuty?
- 7. Gdzie przechowywane są pliki TempData?
- 8. Gdzie przechowywane są zmienne javascript
- 9. Gdzie są przechowywane zarejestrowane serwery?
- 10. Sprawdź, czy dwa typy ogólne są równe
- 11. Gdzie są przechowywane ustawienia związane z JNLP
- 12. Gdzie są zapisane makra przechowywane w Notepad ++?
- 13. Gdzie wartości r przechowywane są w C++?
- 14. Gdzie są przechowywane zmienne w Pythonie?
- 15. Gdzie są przechowywane projekty w Eclipse?
- 16. Gdzie są przechowywane uprawnienia w systemie Android?
- 17. Gdzie są metody przechowywane w pamięci?
- 18. Gdzie są przechowywane vary w Nodejs?
- 19. Jak porównać typy ogólne?
- 20. Gdzie są przechowywane konfiguracje debugowania Eclipse CDT?
- 21. Gdzie przechowywane są sole hasła laravel?
- 22. Gdzie są przechowywane obrazy docker przez boot2docker?
- 23. Gdzie są przechowywane statyczne bloki CMS Magento?
- 24. Gdzie przechowywane są dane dziennika CloudWatch?
- 25. Gdzie są przechowywane recenzje produktów magento 1.5?
- 26. Ustaw opcje .... gdzie są one przechowywane
- 27. Gdzie są przechowywane pliki logcat systemu Android?
- 28. Gdzie są przechowywane obrazy emulatora Androida?
- 29. Czy typy enum są przechowywane jako ints w C#?
- 30. Typy klas i typy zależne