我有以下代码。
class Test {
int i = 0;
Test() {
System.out.println(this);
System.out.println(this.i);
}
}
public class Demo extends Test {
int i = 10;
Demo() {
super();
System.out.println("calling super");
System.out.println(this);
System.out.println(this.i);
}
public static void main(String[] args) throws IOException {
Demo d = new Demo();
}
}
O/P : Demo@2e6e1408
0
calling super
Demo@2e6e1408
10
当我执行程序并打印“this”的值时,在超类构造函数和子类构造函数中,this(地址位置)的值显示为childClassName @ someValue ..我的问题是,当我在超类中打印“this”的值时,为什么我得不到Test的值,即Test @ someVal(Super class).. ASAIK,Super class也会在内存中有一个位置/位置,所以,为什么我没有在第一个SOP中获得Test @ someValue ...
PS:我知道根据引用类型(LHS)引用变量,并根据对象类型(RHS)调用方法。
答案 0 :(得分:10)
当我执行程序并打印“this”的值时,在超类构造函数和子类构造函数中,这个值(地址位置)......
默认System.out.println(this)
的{{1}}输出不内存中实例的地址。它只是类的名称和实例的哈希码,仅此而已。来自the documentation:
类Object的
Object#toString
方法返回一个字符串,该字符串由对象为实例的类的名称,at符号字符“@”和散列码的无符号十六进制表示形式组成。物体。换句话说,此方法返回一个等于值的字符串:
toString
这通常通过将对象的内部地址转换为整数来实现......
但它也说
...但Java TM 编程语言不需要这种实现技术。
...当然,JVM可以根据需要在内存中自由移动实例,但不允许更改getClass().getName() + '@' + Integer.toHexString(hashCode())
。
...当我在超类中打印“this”的值时,为什么我得不到Test,Test @ someVal(Super class)的值。
有一个实例。该实例属于子类。执行hashCode
时,无论是在基类还是子类中执行此操作都无关紧要,它仍然与您正在使用的对象实例相同。一个对象具有特性它从子类获取并且还具有从超类继承的特征,但是没有两个单独的实例;有一个具有组合功能的实例。 System.out.println(this)
不是对象引用,虽然它看起来有点像;它是一种语法机制,专门要求编译器使用实例从超类继承的特性而不是实例的等效特征(如果它们不同)。
答案 1 :(得分:2)
演示是由3个类组成的:自身,测试和对象。但Demo的一个实例是一个对象,在内存中它由超类+自己的字段组成:Test.i
+ Demo.i
(对象没有字段)。