Sto scrivendo uno strumento Bytecode. In questo momento, sto cercando di scoprire come farlo in presenza di oggetti. Vorrei alcuni chiarimenti su due righe che ho letto nella JVM (sezione 4.9.4):Chiarimenti su Bytecode e oggetti
1) "Il verificatore respinge codice che utilizza il nuovo oggetto prima che sia stato inizializzato."
La mia domanda è, cosa significa "utilizza" significa qui? Suppongo che significhi: passarlo come attributo metodo, chiamando GETFIELD
e PUTFIELD
su di esso, o chiamando qualsiasi metodo di istanza su di esso. I loro altri usi proibiti? E credo che ne consegue che sono consentite altre istruzioni come DUP
, LOAD
e STORE
.
2) "Prima metodo richiama un altro metodo di inizializzazione istanza di myClass o sua superclasse diretta su questo, l'unica operazione il metodo può eseguire su questo è assegnare campi dichiarate all'interno miaClasse".
Il che significa che in un metodo <init>
, getField e PUTFIELD sono consentiti prima che un altro <init>
si chiama. Tuttavia, in Java, qualsiasi operazione su un campo di istanza prima di una chiamata a super()
o this()
genera un errore di compilazione. Qualcuno potrebbe chiarirlo?
3) Ho ancora una domanda. Quando viene inizializzato un riferimento a un oggetto e quindi pronto per essere utilizzato liberamente? Dalla lettura di JVMS, ho trovato la risposta che se un oggetto è inizializzato o meno, dipende da ciascun metodo. Ad un certo punto nel tempo, l'oggetto può essere inizializzato per un metodo ma non per l'altro. In particolare, un oggetto viene inizializzato per un metodo quando <init>
chiamato da tale metodo restituisce.
Ad esempio, si consideri che il metodo main()
ha creato un oggetto e ha chiamato <init>
che poi ha chiamato la superclasse <init>
. Dopo il ritorno da super()
, l'oggetto è ora considerato inizializzato da <init>
, ma non è ancora stato inizializzato per main()
. Significa che, in <init>
dopo super()
, posso passare l'oggetto come parametro a un metodo, anche prima di tornare da main().
Qualcuno potrebbe confermare che tutta questa analisi è vera? Grazie per il tuo tempo.
ps: in realtà ho pubblicato la stessa domanda sui forum Sun ma con risposta. Spero di avere più fortuna qui. Grazie.
Aggiornamento
In primo luogo vi ringrazio per le vostre risposte e il tempo. Sebbene non avessi una risposta chiara (avevo molte domande e alcune di esse erano un po 'vaghe), le tue risposte ed esempi, e gli esperimenti successivi, mi sono stati estremamente utili per capire più profondamente come funziona la JVM.
La cosa principale che ho scoperto è che il comportamento del Verificatore differisce da diverse implementazioni e versioni (il che rende il lavoro di manipolazione del bytecode molto più complicato).Il problema sta nel non conformarsi al JVMS, o nella mancanza di documentazione da parte degli sviluppatori del verificatore, o il JVMS ha qualche sottile vaghezza nell'area del verificatore.
Un'ultima cosa, SO Rocks !!! Ho postato la stessa domanda nel forum ufficiale Sun JVM, e fino ad ora non ho ancora ricevuto risposta.
Non è una cattiva idea, ma si deve fare attenzione a questo . In passato il verificatore effettivo era meno severo riguardo alle regole rispetto alle specifiche. È del tutto possibile che tali casi si verifichino ancora. –
Sì, ho scoperto che le diverse implementazioni del Verifier hanno diversi livelli di rigore. Ad esempio, il verificatore JustIce di Apache BCEL non consente STORE su riferimenti a oggetti non inizializzati, mentre Java HotSpot 10.0 fa –