日期:2014-05-20  浏览次数:20721 次

写出如下代码的运行结果并给出解释
Java code
class Test {
  static {
    System.out.println("***");
  }

  public static final String a = "sss";

  public static String test() {
    return "###";
  }
}

public class T {
  public static void main(String[] args) {
    System.out.println(Test.a);
    System.out.println(Test.test());
  }
}



请给出你的理由。。。。。


###########################
老紫竹利用特权,修改一下这个题目
###########################
这个类编译后会生成2个对象
T.class
Test.class

我们把Test.class删除,单独运行T.class 会发生什么呢??

System.out.println(Test.a);
会执行吗?

System.out.println(Test.test());
会执行吗?



------解决方案--------------------

------解决方案--------------------
sss
***
###

------解决方案--------------------
sss
***
###

final类型的特殊性。
------解决方案--------------------
那个final 是关键,他会让编译器优化,并不会去真正使用Test类,而是直接在 
System.out.println(Test.a); 

优化成了 
System.out.println("sss"); 

这就是结果
------解决方案--------------------
java编译器发现class T中使用了class Test时,就会查找Test.class文件,如果没有找到这个文件,就会自动搜索Test.java然后进行编译。
在编译过程中由于final的特性,编译器首先会查找final所修饰的变量然后执行初始化语句,紧接着再根据一般初始化的顺序继续执行其他语句。
所以顺序是:sss *** ###
如果把a前面的final修饰符去掉顺序就不一样,因为初始化的顺序不一样了。
------解决方案--------------------
学习一下
------解决方案--------------------
探讨
sss
***
###

final类型的特殊性。

------解决方案--------------------
mark 学习了

------解决方案--------------------
我修改了帖子,增加了问题。希望能认清楚
final 到底是什么!!!



------解决方案--------------------
试过了,通不过
------解决方案--------------------
support
------解决方案--------------------
Java里一切东西都会出现在类里。很多时候这个特性会很烦琐。毕竟Java仍流有C的血液。
在C的使用习惯里,const是很有意义的,因此java保留了这一特性。也即final存在的初衷。
既然这个是表示常量的,javac理所当然的认为程序运行时JVM不会改变它,于是自作主张的将其改为“Constant”,也就是说跟类没有关系了。这个真真意义上的常量对用户和程序员是透明的,这样比起每次都要重类里加载数据而言,放在常量区的话会提高效率。所以有了上述结果。
------解决方案--------------------
运行结果:
sss
***
###
分析:
1、由于a同时被修饰为static和final,它属于类的资源,就是类在被加载进内存的时候(也就是应用程序启动的时候)就要已经为此属性分配了内存,即在类的加载之前进行初始化的,可通过类名直接进行访问。所以在以上代码的:System.out.println(Test.a);会先打印出***;此时并没有进行Test类的加载;
2、当执行到System.out.println(Test.test());首先是进行Test类的加载,而static块 ,一般是一个类初始化时运行的代码,注意,是类的初始化,不是对象的初始化。 因此此时先会打印出***,紧接着才调用test()方法,打印出###。
不知道这样解释是否清楚。

------解决方案--------------------
谢谢,各位大虾!我一直以为是static先加载的了
今天有学到了
------解决方案--------------------
咳 
第一反应是:
*** 
SSS
###
看了几位大侠的回答才醒悟...
------解决方案--------------------
sss
***
###

------解决方案--------------------
以下是 javap 结果