2014-12-18 14 views
7

Il formato di file di classe come descritto in http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html contiene tutti i riferimenti ad altre classi nello constant pool come voci di tipo CONSTANT_Utf8.un modo semplice per trovare riferimenti ad altre classi nel file di classe

Ma queste voci non sono solo riferimenti a classi ma anche valori letterali di classe, nomi di metodi, campi e cosa no.

In un primo tentativo ho pensato che sarebbe stato sufficiente utilizzare le voci della piscina costanti a cui fanno riferimento altre voci constant_pool di tipo CONSTANT_Class, CONSTANT_NameAndType e CONSTANT_MethodType

Ma questi non sembrano includere parametri di tipo e annotazioni. Un'ulteriore lettura delle specifiche sembra suggerire che ho bisogno di analizzare cose come RuntimeVisibleAnnotations e costrutti simili per identificare le voci costanti del pool costanti. Il che significa che devo analizzare più o meno il file di classe completo.

Ma l'idea alla base del parsing del file di classe era che sarebbe stato più semplice utilizzare una libreria come ASM, perché pensavo che sarebbe stato sufficiente per interpretare il pool costante.

La mia domanda è: esiste un modo per identificare in modo affidabile tutte le classi a cui si fa riferimento in un file di classe semplicemente interpretando poco più del pool costante?

+0

Ovviamente, 'RuntimeInvisibleAnnotations' può anche fare riferimento a tipi (la sua struttura è identica a' RuntimeVisibleAnnotations'). E ci sono 'RuntimeVisibleParameterAnnotations' e' RuntimeInvisibleParameterAnnotations'. E se è compilato con informazioni di debug, ci possono essere 'LocalVariableTable' e' LocalVariableTypeTable'. Ciascuno di essi (e l'attributo 'Signature') può dare alle costanti di' UTF8' un significato di tipo o firma ... – Holger

risposta

2

I tipi di annotazione che non possono essere caricati da un programma di caricamento classe vengono ignorati da questo caricatore di classi e appariranno semplicemente invisibili in fase di runtime. Presumo che questo sia il motivo per cui i tipi a cui fa riferimento un'annotazione sono non memorizzati nel pool costante in cui la risoluzione di un tipo sconosciuto impedisce il caricamento corretto della classe. Le annotazioni sono attributi di codice, ovvero metadati e non dovrebbero essere collegati in profondità alla classe evitando una voce di pool costante.

Si richiede pertanto anche l'introspezione di RuntimeVisibleAnnotations che vivono al di fuori del pool costante. Tuttavia, se il pool costante non contiene una stringa RunntimeVisibleAnnotations, il tuo approccio funziona. ASM ha comunque un piccolo overhead, quindi lo userei comunque.