计划从今天开始,模仿一下jythoner大哥,不过不是Java每日一题,而是Java每日一惑。主要是以Java的基本语法和一些虚拟机的特性为出发点,巩固一下自己Java基础知识,并抛砖引玉。我想这个对有些面试还是很有帮助的,所以搜集了一些书上的,网上的Tips。供大家参考,并在每个题目附上自己的理解,如有理解有错的地方和做的不好的地方请大家指出,我们共同进步。我尽量每天都出个Tips,当然大家的支持就是我最大的动力。
下面就先看今天的第一惑,直接上代码:
package cantellow.text8; public class TestStaticFinal { /** * @author cantellow */ public static void main(String[] args) { // TODO Auto-generated method stub String var1 = StaticFinal.stringStaticFinal; System.out.println(var1); String var2 = Static2.stringStatic; System.out.println(var2); StaticFinal.finalprint(); Static2.Print(); } } class StaticFinal { final static String stringStaticFinal = "This is Static and Final string"; static { System.out.println("开始初始化StaticFinal类的静态变量和静态初始化块"); System.out.println(stringStaticFinal); } public final static void finalprint() { System.out.println("This is finalprint()"); } } class Static2 { static String stringStatic = "This is static string"; static { System.out.println("开始初始化Static2类的静态变量和静态初始化块"); System.out.println(stringStatic); } public static void Print() { System.out.println("This is print()"); } }
输出结果:
This is Static and Final string 开始初始化Static2类的静态变量和静态初始化块 This is static string This is static string 开始初始化StaticFinal类的静态变量和静态初始化块 This is Static and Final string This is finalprint() This is print()
问题:为什么访问StaticFinal类的stringStaticFinal字段时,StaticFinal类没有被初始化?
==============================================================
参考理解:
所有的Java虚拟机实现必须在每个类或接口首次主动使用时初始化,当使用某个类的静态方法时和静态字段时,虚拟机就必须保证这个类或接口已经被初始化,如果没有被初始化,就必须要先初始化。但是,用final修饰的静态字段除外,它被初始化为一个编译时的常量表达式。所以,我们这里看到:访问StaticFinal类的stringStaticFinal字段时,StaticFinal类并没有被初始化。而访问没有final修饰的Static2类的静态字段时,引发了Static2类的初始化。而且,静态方法不管有没有final字段修饰都会引发类的初始化。初始化过一次的类就不会再初始化了,这一点也可以从Static2类看出。