public class Test_1_2 { static int b = 9; static int c; static { b = 6; System.out.println("----------------"); } public static void main(String[] args) { System.out.println(Test_1_2.b); } }
LZ执行一下吧 class AB { static{ System.out.println("我来了AB"); } private static AB obj = new AB(); public static int num1 ; public static int num2 = 0; private AB() { System.out.println("我来了AB构造函数"); num1++; num2++; // ystem.out.println(+num1); // ystem.out.println(+num2); } public static AB getInstance() { System.out.println("我来了实例"); return obj; } } public class CsdnTest { static{ System.out.println("我来了CsdnTest"); } public static void main(String[] args) { System.out.println("我来了main"); AB obj = AB.getInstance(); System.out.println("obj.num1=" + obj.num1); System.out.println("obj.num2=" + obj.num2); double f = 111231.5585; BigDecimal b = new BigDecimal(f); double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); System.out.println(f1); } }
还是之后才执行的呢? 也许debug并不反映底层真实加载情况,但debug一下会发现
已经输出了--------后才进入ClassLoader ,难道说加载中的初始化静态成员部分不需要
类加载器参与吗? 希望我表述清楚了 期待了解的朋友稍微指点一下
再好好看看,why。
class AB {
static{
System.out.println("我来了AB");
}
private static AB obj = new AB();
public static int num1 ; public static int num2 = 0; private AB() {
System.out.println("我来了AB构造函数");
num1++;
num2++;
// ystem.out.println(+num1);
// ystem.out.println(+num2);
} public static AB getInstance() {
System.out.println("我来了实例");
return obj;
}
}
public class CsdnTest {
static{
System.out.println("我来了CsdnTest");
}
public static void main(String[] args) {
System.out.println("我来了main");
AB obj = AB.getInstance();
System.out.println("obj.num1=" + obj.num1);
System.out.println("obj.num2=" + obj.num2);
double f = 111231.5585;
BigDecimal b = new BigDecimal(f);
double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
System.out.println(f1);
}
}
当你运行java Test_1_2的时候,实际是执行Test_1_2.main(), 当虚拟机启动某个被表明为启动类的类(即含有main方法的那个类)这是一种主动引用。JVM规定了几种主动引用(看这里:JVM Specification - 5.5 Initialization,点这里下载Java 7 版)。
在这种情况下,虚拟机要先初始化这个类。但初始化前先要load,然后link(关于load,link,initialize前看上面的Specification)。
所以:1: load Test_1_2 ---》2: link Test_1_2 --》 3: initialize Test_1_2看初始化部分,初始化类,简单点说就是按你在类中的书写顺序执行执行那些static变量的初始化和static块。(static变量和static块都按照出现的先后顺序全部放在一个叫<cinit>的方法中。)
在执行static块中的 System.out.println("----------------");时,这里调用了System.out这个static字段。会引起PrintStream(System.out)类的load,link,initialization...你说先输出"----------------"然后又进入了ClassLoad,但是你打印语句之后在没有需要要加载的类了。。所以我觉得应该不可能。在断点跑到System.out.println("----------------")这句时又会跑进ClassLoader,这时应为要加载PrintStream。
http://www.lunwenwa.com/