写出如下代码的运行结果并给出解释Java codeclass Test {static {System.out.println(***)}public stat
写出如下代码的运行结果并给出解释
Java codeclass 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 结果
BatchFile codeCompiled from "T.java"public class T extends java.lang.Object{public T(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: returnpublic static void main(java.lang.String[]); Code: 0: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #22; //String sss 5: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 11: invokestatic #30; //Method test20080713/Test.test:()Ljava/lang/String; 14: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 17: return}Compiled from "T.java"class Test extends java.lang.Object{public static final java.lang.String a;static {}; Code: 0: getstatic #13; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #19; //String *** 5: invokevirtual #21; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: returnTest(); Code: 0: aload_0 1: invokespecial #30; //Method java/lang/Object."<init>":()V 4: returnpublic static java.lang.String test(); Code: 0: ldc #36; //String ### 2: areturn}[解决办法] 又学了一招[解决办法] 学习了[解决办法] 原来是这样的,终于有点懂了[解决办法] 一起学习了。[解决办法] 都是final static惹得祸[解决办法] 探讨 我修改了帖子,增加了问题。希望能认清楚 final 到底是什么!!! [解决办法] 对了,还有一个final参数, final argument 相当于c/c++中的 const argument[解决办法] 这个是经常考得一个题目 远行一遍就明白多了[解决办法] 学习了,谢谢![解决办法] 晕,我还以为***先执行呢[解决办法] 学习了[解决办法] 受益匪浅[解决办法] 学习![解决办法] ding ding[解决办法] 探讨 引用: sss *** ### final类型的特殊性。 同意[解决办法] 学习了。Java的类,让人造成误解,以为写到类里的代码,就都属于这个类。其实是个常量。[解决办法] 探讨 谢谢,各位大虾!我一直以为是static先加载的了 今天有学到了[解决办法] 有点意思[解决办法] 对final static String a的赋值放到static{}里,执行结果就是先输出sss了,因为final static类型的变量,必须先初始化值才可以。 [解决办法]
探讨 引用: 引用: sss *** ### final类型的特殊性。 同意 [解决办法] 顶[解决办法] 高手如云[解决办法] 楼主的例子是外部调用类的静态final常量, 并且该常量初始化语句是编译时的常量表达式。 只能说这种情况不符合"类首次主动被使用时"的初始化规则,因此不会导致类的初始化。运行以下代码的结果表明,外部调用类的编译时静态final常量,甚至都不会导致Test类被ClassLoader加载,也就更不会做类的初始化动作了。 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); } } 编译Test.java和T.java 在命令行执行:java -verbose T 以下为部分输出: ........................................................................... [Loaded java.security.AllPermission from C:\Program Files\Java\j2re1.4.2_09\lib\rt.jar] [Loaded java.security.UnresolvedPermission from C:\Program Files\Java\j2re1.4.2_09\lib\rt.jar] [Loaded java.security.BasicPermissionCollection from C:\Program Files\Java\j2re1.4.2_09\lib\rt.jar] [Loaded java.lang.Long$1 from C:\Program Files\Java\j2re1.4.2_09\lib\rt.jar] [Loaded java.security.Principal from C:\Program Files\Java\j2re1.4.2_09\lib\rt.jar] [Loaded java.security.cert.Certificate from C:\Program Files\Java\j2re1.4.2_09\lib\rt.jar] [Loaded T] sss [Loaded java.lang.Shutdown from C:\Program Files\Java\j2re1.4.2_09\lib\rt.jar] [Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\j2re1.4.2_09\lib\rt.jar][解决办法] sss *** ### 因为static不需要初始化,可 以直接调用