2014-12-18 23 views
7

Format pliku klas opisany w http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html zawiera wszystkie odniesienia do innych klas w constant pool jako wpisy typu CONSTANT_Utf8.łatwy sposób na znalezienie referencji do innych klas w pliku klasowym

Ale te pozycje to nie tylko odniesienia do klas, ale także literały klas, nazwy metod, pola i co nie.

W pierwszej próbie myślałem, że wystarczy użyć stałe wstęp basen odwołuje innych wpisów constant_pool typu CONSTANT_Class, CONSTANT_NameAndType i CONSTANT_MethodType

ale te nie wydają się zawierać parametry typu i adnotacje. Dalsze czytanie specyfikacji wydaje się sugerować, że muszę przeanalizować takie rzeczy, jak RuntimeVisibleAnnotations i podobne konstrukcje, aby zidentyfikować odpowiednie wpisy puli stałej. Co oznacza, że ​​muszę przeanalizować mniej więcej kompletny plik klasy.

Ale sama idea analizy pliku klasowego była taka, że ​​byłoby prostsze niż użycie biblioteki takiej jak ASM, ponieważ uważałem, że wystarczy zinterpretować stałą pulę.

Moje pytanie brzmi: czy istnieje sposób na niezawodną identyfikację wszystkich klas przywoływanych w pliku klasy poprzez interpretację niewiele więcej niż puli stałej?

+0

Oczywiście "RuntimeInvisibleAnnotations" może również odnosić się do typów (jego struktura jest identyczna z "RuntimeVisibleAnnotations"). Istnieją również "RuntimeVisibleParameterAnnotations" i "RuntimeInvisibleParameterAnnotations". A jeśli jest skompilowany z informacjami debugowania, mogą istnieć 'LocalVariableTable' oraz' LocalVariableTypeTable'. Każdy z nich (i atrybut "Signature") może nadać stałe 'UTF8' typowi lub sygnaturze, co oznacza ... – Holger

Odpowiedz

2

Typy adnotacji, które nie mogą być ładowane przez moduł ładujący klasy, są ignorowane przez ten moduł ładujący klasy i po prostu wydają się niewidoczne w czasie wykonywania. Zakładam, że z tego powodu typy, do których odwołuje się adnotacja, są przechowywane w puli stałej, a rozdzielczość nieznanego typu uniemożliwi pomyślne załadowanie klasy. Adnotacje to atrybuty kodu, tj. Metadane i nie należy ich łączyć z klasą, unikając wpisania stałej puli.

Konieczne jest również dokonanie introspekcji RuntimeVisibleAnnotations, które znajdują się poza stałą pulą. Jeśli jednak pula stała nie zawiera ciągu RunntimeVisibleAnnotations, Twoje podejście działa. ASM ma jednak bardzo niewielki narzut, więc mimo wszystko go wykorzystam.