黑马_张伟 发表于 2012-11-27 15:52
package questions;
class Demo
class Demo
{
static Demo d = new Demo();
Demo()
{
System.out.println("demo"+"----"+d+"------"+this);
}
}
class DemoDemo
{
public static void main(String[] args)
{
System.out.println(new Demo());
System.out.println(Demo.d);
}
}
打印结果
demo----null------Demo@c05d3b
demo----Demo@c05d3b------Demo@128f6ee
Demo@128f6ee
Demo@c05d3b
个人分析:首先主函数进入程序,因为类 Demo 中static Demo d = new Demo() 被静态修饰,所以程序从主函数一进入便执行“static Demo d = new Demo() ”,而不是执行主函数中的
“System.out.println(new Demo())”。
详细分析:
执行“static Demo d = new Demo() ”这句话,这句话是这样执行的,先执行 new Demo(),new Demo其实就是在调用Demo类中的构造函数,所以就执行了一次构造函数里面的打印输出语句
“System.out.println("demo"+"----"+d+"------"+this)”,结果是demo----null------Demo@c05d3b,打印出来的 "demo" 和 "----" 就不用说多说了,直接打印字符串,其中的null是打印的d的默认初始化值,为什么这个
d的值是null,而不是一个地址值呢?原因很简单,因为这个时候程序还在执行new Demo(),即调用Demo类里面的构造函数,也就是说这个时候还在执行Demo类里面的构造函数的打印语句
“System.out.println("demo"+"----"+d+"------"+this)”,所以这个时候根本就没有把地址值赋给 变量d,后面的this就是当前对象,也就是打印new Demo()这个对象的地址值。这算是new Demo()这句话执行完成,接着便是便是把 new Demo()的地址值赋给 变量d,这个时候 static Demo d = new Demo()这句话才算是真正执行完成。整个过程可以简单点来形容,就是先调用构造函数,然后再把new Demo()的地址值给了静态变量d。
接下来执行主函数中的“System.out.println(new Demo())”,这句话也是先执行new Demo(),调用类Demo里面的构造函数,然后执行Demo类里面的构造函数中的打印输出语句
“System.out.println("demo"+"----"+d+"------"+this)”,
打印结果便是:demo----Demo@c05d3b------Demo@128f6ee,然后就是执行
System.out.println(new Demo())这句话中的打印部分,打印new Demo()的地址值,打印结果Demo@128f6ee,这个结果刚好“System.out.println("demo"+"----"+d+"------"+this)”,
里面的this地址一样,之所以一样,是因为本来就是new Demo()在掉用Demo类中的构造函数,里面的this当然就是new Demo()自己,所以地址值也就一样。
最后一句话:System.out.println(Demo.d),这句话的作用是用来验证的,看一下前面分析是否正确,
事实证明这个时候的d的地址值和前面的是一样的,都是Demo@c05d3b,所以前面分析就应该没问题。 |