【问题标题】:Is 'this' reference stored on call stack in Java?'this' 引用是否存储在 Java 的调用堆栈中?
【发布时间】:2012-05-01 17:09:06
【问题描述】:

我们已经知道,当我们在 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的实现?

更新

我知道this 是一个关键字而不是一个普通的引用变量,但我对这个示例的主要关注点是 JVM 如何知道对象在堆中的位置?

或者换句话说,JVM如何在运行时知道成员方法的当前对象是什么,以便他们可以访问那些实例变量?

【问题讨论】:

  • 如果我没记错的话,this 被(隐式)作为第一个参数传递给方法
  • 值得注意的是,本机代码和 CPU 线程堆栈中发生的内容与虚拟机字节码中描述的内容可能完全不同。例如如果 test() 方法是内联的,则没有方法调用,也没有 this 值或参数添加到堆栈中。

标签: java this callstack calling-convention


【解决方案1】:

围绕 stackmachine 模型构建的大多数语言都可以像您描述的那样工作。这包括 Java、.NET 和 C++。

这样想:实例方法的代码很可能在一个类的所有实例之间共享,复制每个实例的数据以外的任何内容都没有多大意义,如果那个公共部分(代码对于方法实现,请记住它只是计算机的内存)无论如何在所有实例中都是相同的。

因此,实例方法与静态(在 Java 和 .NET 中)方法的区别在于添加到每个方法签名中的隐式 this 参数。隐含的 this 参数表示该方法应该操作的实例。而且由于传递给方法的参数很可能发生在堆栈上,是的,这个参数将存储在堆栈上。 (请参阅 http://zeroturnaround.com/articles/java-bytecode-fundamentals-using-objects-and-calling-methods/#objects 对于 Java,它在 .NET 中非常相似)。 this 参数在调用方法之前作为第一个参数压入堆栈,然后是所有其他参数。

现在,这描述了虚拟机的模型。如果 JITed 机器代码真的会通过堆栈或寄存器(或以任何其他方式)传递 this 参数,则完全特定于实现并对 VM 透明。

在您的示例代码中要注意的另一件事是您两次使用了变量名“y”,因此在该方法中,局部变量“y”将隐藏实例变量,除非您使用“this”明确限定它'。

【讨论】:

    【解决方案2】:

    您的问题是:- 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.
    

    【讨论】:

      猜你喜欢
      • 2021-06-28
      • 2016-03-05
      • 2013-03-07
      • 2017-09-06
      • 2018-04-21
      • 2010-09-15
      • 2012-04-17
      • 1970-01-01
      • 2015-05-03
      相关资源
      最近更新 更多