Kev*_*ark 30 java oop this-keyword
考虑:
class TestParent{
public int i = 100;
public void printName(){
System.err.println(this); //{TestChild@428} according to the Debugger.
System.err.println(this.i); //this.i is 100.
}
}
class TestChild extends TestParent{
public int i = 200;
}
public class ThisTest {
public static void main(String[] args) {
new TestChild().printName();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道有类似的问题已被提出,但我无法对Java中的'this'变量有一个明确的理解.
让我试着解释一下我是如何理解上面图像的结果的.
因为它是一个new TestChild()调用printName()方法this的TestChild对象,所以根据调试器,第6行中的变量被设置为一个对象 - {TestChild @ 428}.
但是,由于Java没有虚拟字段 - 我不完全确定这意味着什么,但我从概念上理解它与Java方法相反,它支持多态性 - 在编译时this.i设置为100 TestParent.
所以不管是什么this,this.i在一个TestParent方法中总是会i成为TestParent类中的变量.
我不确定我的理解是否正确所以如果我错了请纠正我.
而且,我的主要问题是,
如何将this变量设置为调用方法的当前对象?它是如何实际实现的?
Gho*_*ica 42
从本质上讲,两者之间没有区别
this.foo()
Run Code Online (Sandbox Code Playgroud)
和
anyObject.foo()
Run Code Online (Sandbox Code Playgroud)
因为两者都以同样的方式"实施".请记住,"最终""面向对象只是一种抽象,在"现实"中发生的事情是这样的:
foo(callingObject)
Run Code Online (Sandbox Code Playgroud)
换句话说:无论何时使用某个对象引用来调用方法......最后都没有对某个对象进行调用.因为在汇编程序和机器代码的深处,不存在诸如"对某事物的调用"之类的东西.
真正发生的是对函数的调用; 第一个(源代码级别隐式/不可见)参数是该对象.
顺便说一句:你实际上可以用Java写下来:
class Bar {
void foo(Bar this) { ... }
Run Code Online (Sandbox Code Playgroud)
以后用
new Bar().foo();
Run Code Online (Sandbox Code Playgroud)
对于this.fieldA,最后:你有一个对内存中某个位置的引用; 和一个表,告诉你哪个"偏移"你会找到fieldA.
编辑 - 仅供记录.如果你对foo(Bar this)的更多细节感兴趣 - 你可以转向这个问题 ; 在Java规范中提供详细信息!
Tom*_*son 18
这里发生的事情是,有两个完全不同的领域都叫做i; 使用他们的全名,一个是TestParent::i一个,一个是TestChild::i.
因为该方法printName的定义是TestParent,当它引用时i,它只能看到TestParent::i,它被设置为100.
而当你设置i为200时TestChild,两个被调用i的字段都是可见的,但是因为它们具有相同的名称,所以TestChild::i 隐藏 TestParent::i,并且最终设置TestChild::i并保持TestParent::i不变.