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

use*_*758 5 java bytecode

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

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

更新:我指的是字节码

Jon*_*eet 7

JVM规范第2.6.1节似乎认为它只是取决于它是否是一个静态(类)方法或实例方法:

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

这是局部变量的初始值; 请参阅Mike Strobel的答案,了解在该方法中明确更改的示例.

  • @ErstwhileIII"JVM规范,第2.6.1节"对你来说不够权威吗? (4认同)

Mik*_*bel 2

我知道有两种情况当 local #0 没有引用时this

  1. 在静态方法中,如 @JonSkeet 所记录。
  2. 在本地 #0 已被其他值覆盖的实例方法中。

第二种情况是完全有效的。Local #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
Run Code Online (Sandbox Code Playgroud)

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

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