A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张权 中级黑马   /  2012-11-27 12:06  /  1193 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张权 于 2012-11-27 23:34 编辑

class Demo
{
                static Demo d = new Demo();
                Demo()
                {
                                System.out.println("demo");
                }        
}
class DemoDemo
{
                public static void main(String[] args)
                {
                                System.out.println(new Demo());
                                
                        
                }        
}
这段代码打印结果如下:
demo
demo
一个地址值
问题1:为什么不是先打印地址值呢?
问题2:先看下面代码,为了方便,就把前面的代码叫代码1,下面的代码叫代码2吧。。
class Demo
{
                                Demo()
                {
                                System.out.println("demo");
                }        
}
class DemoDemo
{
                public static void main(String[] args)
                {
                                System.out.println(new Demo());
                                
                        
                }        
}
代码2打印结果:
demo
地址值
代码一之所以会有两个demo,就因为代码一多了 static Demo d = new Demo();这句话,所以,我想问的是,代码一打印结果demo的打印顺序,到底第一个demo是 static Demo d = new Demo()这句话打印的结果呢?还是System.out.println(new Demo())这句话的结果???
最好画个图

评分

参与人数 2技术分 +1 黑马币 +2 收起 理由
马海保 + 2 神马都是浮云
古银平 + 1 神马都是浮云

查看全部评分

6 个回复

倒序浏览
        static class Demo
         {                               
                         static Demo d = new Demo();
                         Demo()
                         {       
                               System.out.println("demo"+"---"+d);
                         }        
         }
        public static void main(String[] args) {
                System.out.println(new Demo());
        }
}
//demo---null  先打印的是静态变量d的demo ,静态先于对象而存在,所以d=unll
//demo---@6276e1db         创建匿名对象,调用构造方法
//6ae6235d

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
class Demo
{
                static Demo d = new Demo();
                Demo()//在new对象时构造函数会比给属性d赋值先执行,所以结果中第一个“Demo”是“System.out.println(new Demo())这句话的结果”                {
                                System.out.println("demo");
                }        
}
class DemoDemo
{
                public static void main(String[] args)
                {
                                System.out.println(new Demo());//会先执行new Demo(),等Demo的对象创建完成后再打印地址                                
                        
                }        
}

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
本帖最后由 曹自祥 于 2012-11-27 15:44 编辑
  1. package pt;

  2. public class XiGou {

  3.         /**
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                 System.out.println(new Demo());
  8.         }
  9. }
  10. class Demo
  11. {
  12.                 static Demo d = new Demo();
  13.                 Demo()
  14.                 {
  15.                    System.out.println(d);//这里稍作修改可以方便地得到解释
  16.                }        
  17. }
复制代码
打印结果:
null   。。。。。。。。。这里是“System.out.println(new Demo())这句话的结果”的打印结果,此时d还没有被赋值,d==null
pt.Demo@4f1d0d
pt.Demo@1fc4bec

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
本帖最后由 黑马_张伟 于 2012-11-27 15:54 编辑

package questions;

class Demo
{
                static Demo d = new Demo();
                Demo()
                {
                                System.out.println("demo"+this);
                }
}
class DemoDemo
{
                public static void main(String[] args)
                {
                                System.out.println(new Demo());
                                System.out.println("d---------"+Demo.d);
                        
                }        
}

-----------------------------------------------------------------
demoquestions.Demo@4f1d0d
demoquestions.Demo@1fc4bec
questions.Demo@1fc4bec
d---------questions.Demo@4f1d0d

-----------------------------------------------------

这么一改你就清楚了。先打的是d;静态变量是随着类的加载而加载产生,所以你用到new Demo()的时候类加载,会优先执行d=new Demo()。结果就明显了

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
谢谢各位的回答
回复 使用道具 举报
张权 中级黑马 2012-11-27 21:10:54
7#
黑马_张伟 发表于 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,所以前面分析就应该没问题。

评分

参与人数 1技术分 +1 收起 理由
崔政 + 1 很详细,值得鼓励

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马