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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 黑马伍哲沂 于 2013-4-11 20:11 编辑
  1. class CodeTest
  2. {
  3.         static
  4.         {
  5.                 System.out.println("1");
  6.         }
  7.         {
  8.                 System.out.println("2");
  9.         }
  10.         public CodeTest ()
  11.         {
  12.                 System.err.println("3");
  13.         }
  14.         public static void main(String[] args)
  15.         {
  16.                 new CodeTest();
  17.         }
  18. }
复制代码
请写出运行结果。
提示:可能大家会觉得静态代码块,构造代码块还有构造函数,毕老师都讲的很清楚了。
也很自信这个程序的答案。但请更细心点。

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

14 个回复

倒序浏览
程序有明显的错误啊,public TestErr()    System.err.println("3");这两个写的应该是这样吧,public CodeTest()     System.out.println("3");如果是这样的话答案应该是
1
2
3
回复 使用道具 举报
秦久启 发表于 2013-4-11 20:06
程序有明显的错误啊,public TestErr()    System.err.println("3");这两个写的应该是这样吧,public CodeT ...

改过来了,构造函数写错了,输出语句没错。就是那样的。
回复 使用道具 举报
程序首先在main方法中执行new CodeTest();会先去加载这个类父类中的静态代码块,如果有的话,你这个类没继承任何类,那么它只会执行自己类中的静态代码块,所以先打印出System.out.println("1");,然后去执行父类中的非静态代码块,也就是构造代码块。父类中没有,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有构造代码块,如果有就执行子类的构造代码块。子类的构造代码块执行完毕再去执行子类的构造方法 System.err.println("3");

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
JVM虚拟机应该是找main函数作为程序的入口,所以会先执行new CodeTest();
按优先级:静态代码块——>非代码块——>构造函数。随后输出的结果应该是
1
2
3

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
1
2
3

初始化顺序是

父类静态成员变量和静态初始化块,按在代码中出现的先后顺序,静态代码块和静态变量参与共同的排序
子类静态成员变量和静态初始化块,按在代码中出现的先后顺序,静态代码块和静态变量参与共同的排序
父类非静态成员变量和代码块,按在代码中出现的先后顺序,非静态代码块和非静态变量参与共同的排序
父类构造器
子类非静态成员变量和代码块,按在代码中出现的先后顺序,非静态代码块和非静态变量参与共同的排序
子类构造器

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1 赞一个!

查看全部评分

回复 使用道具 举报
我觉得只要你看了毕老师的视频这题没理由出错哦
回复 使用道具 举报
李尧 高级黑马 2013-4-11 23:44:39
8#
我发现我不会.....求楼主给答案.....{:soso_e135:}
回复 使用道具 举报
对象的初始化过程:
从main函数入口开始,new用到了CodeTest类,所以先把CodeTest.class加载进内存
执行该类的static代码块,所以首先输出 1
在堆内存中开辟空间,分配内存地址。
在堆内存中建立对象的特有属性,并进行默认 初始化
对属性进行显示初始化
对对象进行构造代码块初始化 所以接着输出 2
对对象进行与之对应的构造函数初始化,所示输出 3
将内存地址赋给栈内存中的变量,指向堆内存中的对象。

所以输出顺序是1 2 3
回复 使用道具 举报
李尧 发表于 2013-4-11 23:44
我发现我不会.....求楼主给答案.....

刚开始有人在说err这个错误流,有新开启线程,然后我把程序改成这样:
  1. class TestErr
  2. {
  3.         static
  4.         {
  5.                 System.err.println("1");
  6.         }
  7.         {
  8.                 System.err.println("2");
  9.         }
  10.         public TestErr()
  11.         {
  12.                 System.err.println("3");
  13.         }
  14.         public static void main(String[] args)
  15.         {
  16.                 new TestErr();
  17.         }
  18. }
复制代码
如果真的是开启了新线程的话,这个答案就应该有不确定的顺序输出结果。于是,我去看源代码,发现用的是native方法,所以看不出什么问题。但我反复实验,都是123.这里就出现了两个疑问。
1:这个题目如果单纯考静态、构造代码快和构造函数的执行顺序,干嘛第三个输出语句要用错误流?(可能性是有很多,比如,有人会不认识err,直接说编译错,但觉得真多余了)
2:out和err这两个流,到底有什么区别?
面试的原题,我的理解是答案为123。因为就算开启新线程,没意外的话,也要构造函数执行了之后才开启。
回复 使用道具 举报
黑马伍哲沂 发表于 2013-4-12 12:46
刚开始有人在说err这个错误流,有新开启线程,然后我把程序改成这样:如果真的是开启了新线程的话,这个 ...

我就是不明白这个err流吖,你没改之前的代码,输出结果是不确定的.....我用eclipse测试了.每次运行结果顺序都不一样.
回复 使用道具 举报
李尧 发表于 2013-4-12 15:28
我就是不明白这个err流吖,你没改之前的代码,输出结果是不确定的.....我用eclipse测试了.每次运行结果顺序 ...

啊?  那我也迷惑了。我再试试,我用命令行,运行了几十次了。而且还把三个块里面,分别加了500次循环,全部改成err,也没出现不一样的结果。  这我就真纳闷了,看来要多查资料了。
回复 使用道具 举报
李尧 发表于 2013-4-12 15:28
我就是不明白这个err流吖,你没改之前的代码,输出结果是不确定的.....我用eclipse测试了.每次运行结果顺序 ...

我用eclipse测试,确实不确定。多次运行,出现的结果暂时发现有123,132,312。132的输出是13在同一行,其它都是单独成行。  再将程序加一部分循环。
  1. class TestErr
  2. {
  3.         static
  4.         {
  5.                 for (int x = 1; x <= 100; x++)
  6.                 {
  7.                         if (x % 20 == 0)
  8.                                 System.out.println();
  9.                         System.out.print("1");
  10.                 }
  11.         }
  12.         {
  13.                 for (int x = 1; x <= 100; x++)
  14.                 {
  15.                         if (x % 20 == 0)
  16.                                 System.out.println();
  17.                         System.out.print("2");
  18.                 }
  19.         }

  20.         public TestErr()
  21.         {
  22.                 for (int x = 1; x <= 100; x++)
  23.                 {
  24.                         if (x % 20 == 0)
  25.                                 System.out.println();
  26.                         System.err.print("3");
  27.                 }
  28.         }

  29.         public static void main(String[] args)
  30.         {
  31.                 new TestErr();
  32.         }
  33. }
复制代码
在eclipse中,3构造函数中下面语句无效:
if (x % 20 == 0)
        System.out.println();
而且输出顺序却似乎固定了,怎么运行都是1和2打印完,才打印3,但格式控制无效。
百度了一些资料,没看到合适的解释。但应该与线程无关。如果你有新的发现,期待分享。
回复 使用道具 举报
黑马伍哲沂 发表于 2013-4-12 18:59
我用eclipse测试,确实不确定。多次运行,出现的结果暂时发现有123,132,312。132的输出是13在同一行,其 ...

查了半天只有下面这种说法比较靠谱,应该不是多线程的问题.
out会缓冲,err是立刻打印.
用标准出错打印出来的东西可以马上显示在屏幕,而标准输出打印出来的东西可能要再积累几个字符才能一起打印出来。如果你在应用中混用标准输出和标准出错System.err打出来的信息常常会跑到System.out信息的前面去。。。
回复 使用道具 举报
李尧 发表于 2013-4-12 19:51
查了半天只有下面这种说法比较靠谱,应该不是多线程的问题.
out会缓冲,err是立刻打印.
用标准出错打印出来 ...

看来只能这么理解了。我找到的http://www.cjsdn.net/post/print?bid=1&id=5241意思和这也差不多。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马