[英]Java - How does a method know which object "this" refers to?
假设我们有一堂课
public class ThisTest {
String username;
ThisTest(String s) {
this.username = s;
}
public void sayHello() {
System.out.println("Hello " + this.username);
}
public static void main(String args[]) {
ThisTest a = new ThisTest("Jack");
ThisTest b = new ThisTest("George");
a.sayHello();
b.sayHello();
}
}
输出(如预期):
Hello Jack
Hello George
我的问题是:在 sayHello 方法中,运行时如何确定“this”指的是堆上的哪个对象实例。
在编译时,方法调用是否传递了对调用对象(a 或 b)的隐藏引用,然后使用“this”关键字访问该对象? - 这就是 C++ 所做的。
或者,“this”是在构造对象时创建的堆上对象的隐藏实例变量吗?
或者,是否有其他某种机制可以让 sayHello 方法知道“this”指的是哪个对象?
本质上,“this”是如何在 Java 的编译器级别实现的。
从 Java 编程语言的角度来看,没有强制实现,因为即使编译为 Java 字节码也被认为是“正常的”,但不是必需的。
Java 语言规范,第 1 章。介绍Java 编程语言通常编译为The Java Virtual Machine Specification, Java SE 8 Edition 中定义的字节码指令集和二进制格式。
要了解在为 Java 虚拟机编译时如何实现this
参考,我们必须参考提到的The Java Virtual Machine Specification :
2.6.1. 局部变量
每个帧(第 2.6 节)都包含一个变量数组,称为其局部变量。 帧的局部变量数组的长度在编译时确定,并以类或接口的二进制表示以及与帧关联的方法的代码提供(第 4.7.3 节)。
…
局部变量通过索引寻址。 第一个局部变量的索引为零。 […]
…Java 虚拟机使用局部变量在方法调用时传递参数。 在类方法调用中,任何参数都在从局部变量0开始的连续局部变量中传递。 在实例方法调用中,局部变量0始终用于传递对调用实例方法的对象的引用(Java 编程语言中的
this
)。 随后在从局部变量1开始的连续局部变量中传递任何参数。
换句话说,在 Java 字节码中, this
被编译为一个局部变量(索引为零),在进入方法时使用对象引用进行预初始化。 可以使用用于访问参数变量或显式声明的局部变量的相同字节码指令来访问它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.