Java - 第0个局部变量何时不是'this'?

时间:2014-03-04 14:41:20

标签: java bytecode

在Java方法的局部变量中,第0个局部变量何时不会引用'this'?

我可以将静态方法看作反例,还有其他方法吗?

更新:我指的是字节码

2 个答案:

答案 0 :(得分:7)

JVM specification section 2.6.1似乎认为它只取决于它是静态(类)方法还是实例方法:

  

Java虚拟机使用局部变量在方法调用上传递参数。在类方法调用中,任何参数都在从局部变量0开始的连续局部变量中传递。在实例方法调用中,局部变量0总是用于传递对调用实例方法的对象的引用(这在Java中)编程语言)。随后,任何参数都在从局部变量1开始的连续局部变量中传递。

就局部变量的初始值而言;请参阅迈克斯特罗贝尔的答案,其中一个例子是在方法中明确改变的。

答案 1 :(得分:2)

当本地#0未引用this时,我知道有两种情况:

  1. 在静态方法中,如@JonSkeet所述。
  2. 在本地#0被其他值覆盖的实例方法中。
  3. 第二种情况完全有效。本地#0仅保证在进入实例方法时引用this。在该方法中,关于时隙#0没有任何固有的“特殊”;它可以(重新)写成任何其他插槽(正式参数使用的那些插槽)。请考虑以下Jasmin格式的示例:

    .class public HelloWorld
    .super java/lang/Object
    
    .method public <init>()V
      .limit stack 2
      aload_0
      invokenonvirtual java/lang/Object/<init>()V
      ldc              "Hello World."
      astore_0
      getstatic        java/lang/System/out Ljava/io/PrintStream;
      aload_0
      invokevirtual    java/io/PrintStream/println(Ljava/lang/String;)V
      return
    .end method
    
    .method public static main([Ljava/lang/String;)V
      .limit stack 2
      new HelloWorld
      invokenonvirtual HelloWorld/<init>()V
      return
    .end method
    

    HelloWorld/<init>()V中,我们用常量字符串覆盖本地#0。因此,aload_0的第二次使用加载除this指针之外的值。同一个局部槽在代码中的不同点引用不同的“概念”变量并不罕见,特别是如果一个类已经通过字节码优化器运行。

    所以,回答你的问题:是的,至少还有一个反例。