2012-04-20 3 views
12

Мы уже знали, что при вызове метода в Java параметры и локальные переменные будут сохранены в стеке.Эта ссылка хранится в стеке вызовов в Java?

Например, следующий код:

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); 
    } 
} 

будет производить стек вызовов, как следующий, когда мы назвали obj.test():

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

Но мне интересно, где же this ссылка в method хранится ? Также он хранится в стеке:

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

Или он хранится на другой территории в памяти? Или он рассчитывается JVM во время выполнения?

Наконец, мне также интересно, имеет ли порядок параметров/переменных из obj.test() в стеке определенный порядок, так же, как C имеет соглашение о вызове, или это зависит от реализации VM?

Update:

Я знаю this это ключевое слово вместо нормальной контрольной переменной, но моя главная забота об этом примере, как JVM знает, где же объект заложен в куче?

Или, другими словами, как JVM знает, что представляет собой текущий объект метода-члена во время выполнения, чтобы они могли получить доступ к этой переменной экземпляра?

+0

, если я правильно помню, 'this' есть (неявно) передается в качестве первого параметра метода – weidi

+1

Ее стоит отметить, что происходит в родном коде и стек процессоров потоков и что описано в байткод для виртуальной машина может быть совершенно другой. например если метод 'test()' inline, в стеке нет вызова метода, значения 'this' или аргументов, добавленных в стек. –

ответ

8

Большинство языков, которые построены вокруг модели stackmachine, будут работать точно так, как вы описали. Сюда входят Java, .NET и C++.

Подумайте об этом так: код для методов экземпляра, скорее всего, будет использоваться для всех экземпляров класса, не имеет смысла копировать что-либо большее, чем данные для каждого экземпляра, если эта общая часть (код для реализации methiod, помните, что все это просто память для компьютера) одинаково во всех случаях.

Так что отличает методы экземпляра от статических (в Java и .NET) методов - это неявный этот параметр, который добавляется к каждой сигнатуре метода. Неявные эти параметры означают экземпляр, над которым должен работать метод. А так как передача параметров методу, скорее всего, происходит по стеку, да, этот параметр будет сохранен в стеке. (см. http://zeroturnaround.com/articles/java-bytecode-fundamentals-using-objects-and-calling-methods/#objects для Java, в .NET это довольно много). Этот параметр передается первым параметром в стек перед вызовом метода, за которым следуют все остальные параметры.

Теперь описывается модель виртуальной машины. Если машинный код JITed действительно передаст этот параметр по стеку или в регистре (или каким-либо другим способом), он будет полностью реализован и прозрачен для виртуальной машины.

Еще одна вещь, о которой стоит остерегаться в вашем примере кода, состоит в том, что вы дважды использовали имя переменной «y», поэтому в методе локальная переменная «y» будет затенять переменную экземпляра, за исключением случаев, когда вы экспроприируете ее с помощью ' это'.

+0

Спасибо, это очень четкое объяснение. :) –

1

Ваш вопрос: - Как JVM знает, что представляет собой текущий объект метода-члена во время выполнения, поэтому они могут получить доступ к этой переменной экземпляра ..

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.