2012-04-20 3 views
12

Sapevamo già che quando chiamiamo un metodo in Java, i parametri e le variabili locali verranno memorizzati nello stack.E 'presente questo riferimento memorizzato nello stack di chiamate in Java?

Ad esempio, il seguente codice:

public class Test 
{ 
    int x = 10; 
    int y = 20; 

    void test(int y) 
    { 
     int z = y; 
     this.x = y; // How JVM knows where is our current object? 
    } 

    public static void main(String [] args) 
    { 
     Test obj = new Test(); 
     obj.test(3); 
    } 
} 

produrrà uno stack di chiamate simile al seguente quando abbiamo chiamato obj.test():

|    | 
+-------------+ 
|  z  | 
|  y  | obj.test() 
+-------------+ 
| obj  | main() 
+-------------+ 

Ma mi chiedo da dove viene this riferimento nel method memorizzata ? È anche memorizzato nello stack come il seguente:

|    | 
+-------------+ 
| this  | 
|  z  | 
|  y  | obj.test() 
+-------------+ 
| obj  | main() 
+-------------+ 

Oppure è memorizzato su un'altra area in memoria? Oppure è calcolato dalla JVM in fase di runtime?

Infine, sono anche curioso di sapere se l'ordine dei parametri/variabile di obj.test() nello stack ha un ordine specifico, proprio come C ha convenzione di chiamata, o dipende dall'implementazione di VM?

Aggiornamento:

So this è una parola chiave al posto di una variabile di riferimento normale, ma la mia principale preoccupazione per questo esempio, è come JVM sa da dove viene oggetto posato nel mucchio?

O in altre parole, in che modo JVM può sapere quale sia l'oggetto corrente di un metodo membro in fase di runtime, in modo che possa accedere a tali variabili di istanza?

+0

se ricordo correttamente, 'this' è (implicitamente) passato come primo parametro a un metodo – weidi

+1

È importante notare che quanto avviene in codice nativo e lo stack filo CPU e quanto descritto in bytecode per un virtuale la macchina può essere completamente diversa. per esempio. se il metodo 'test()' è in linea, non c'è nessuna chiamata al metodo, nessun valore 'this' o argomenti aggiunti allo stack. –

risposta

8

La maggior parte delle lingue costruite attorno a un modello stackmachine funzioneranno esattamente come descritto. Questo include Java, .NET e C++.

Pensateci in questo modo: il codice per i metodi di istanza è molto probabilmente condiviso tra tutte le istanze di una classe, non avrebbe molto senso copiare qualcosa di più dei dati per ogni istanza, se quella parte comune (il il codice per le implementazioni del metiodo, ricorda la sua sola memoria al computer) è lo stesso per tutte le istanze.

Quindi ciò che distingue i metodi di istanza dai metodi statici (in Java e .NET speak) è un parametro implicito che viene aggiunto a ogni firma del metodo. L'implicito questo parametro indica l'istanza su cui il metodo dovrebbe operare. E poiché il passaggio del parametro al metodo è più probabile che si verifichi sopra lo stack, sì, questo parametro verrà memorizzato nello stack. (vedi http://zeroturnaround.com/articles/java-bytecode-fundamentals-using-objects-and-calling-methods/#objects per Java, è piuttosto la stessa cosa in .NET). Questo parametro viene inserito come primo parametro nello stack prima di chiamare il metodo, seguito da tutti gli altri parametri.

Ora, questo descrive il modello della Macchina Virtuale. Se il codice macchina JITed passerà realmente questo parametro sopra lo stack o in un registro (o in qualsiasi altro modo) è completamente specifico e trasparente per la VM.

Un'altra cosa da tenere in considerazione nel codice di esempio è che si è usato due volte il nome della variabile 'y', quindi nel metodo la variabile locale 'y' ombreggia la variabile di istanza, tranne se si qualifica esplicitamente con ' Questo'.

+0

Grazie, questa è una spiegazione molto chiara. :) –

1

La tua domanda è: - come può JVM sapere qual è l'oggetto corrente di un metodo membro in fase di esecuzione, in modo che possano ottenere accesso a tali variabili di istanza.

What i know is , when u call a method with its object then implicitly 
your object reference is passed to your method. like.... 

obj.test(obj,3); 

And at run time this object is cached in this keyword.. that means this is local 
for that method and must be get m/m in stack.