类加载
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);
}
}
--------------------编程问答-------------------- 静态块的方法是最先执行的,所以会输出--------,然后执行main方法 输入6 --------------------编程问答-------------------- 谢谢关注撒 不过我想问的是用java.exe执行主类后ClassLoader是在输出--------之前
还是之后才执行的呢? 也许debug并不反映底层真实加载情况,但debug一下会发现
已经输出了--------后才进入ClassLoader ,难道说加载中的初始化静态成员部分不需要
类加载器参与吗? 希望我表述清楚了 期待了解的朋友稍微指点一下 --------------------编程问答--------------------
在初始化static块之前,是有先调用ClassLoader的loadClass方法加载类的,你下载一份源码,断点到Launcher$AppClassLoader.loadClass方法。在初始化static块,打印--------以前,是有进入这个方法,加载类的。 --------------------编程问答-------------------- 先把手头上的事情完成,
再好好看看,why。。。。 --------------------编程问答-------------------- 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);
}
}
当你运行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。
--------------------编程问答-------------------- static 这个修饰的话是成员变量,当类加载的时候,所有的static都会被加载,然后在进main方法
--------------------编程问答--------------------
是这样的。 --------------------编程问答-------------------- 正解,是在ClassLoader之后执行静态块的
----------------------
http://www.lunwenwa.com/ --------------------编程问答-------------------- 简单的解释:
1、java编译后将所有的static(包括static块,static变量)按顺序全部弄到一个方法里,这个方法叫做<clinit>
2、类load的步骤:装载-连接(验证-准备-解析)-初始化(此时执行<clinit>方法),只有初始化了的类才能使用
补充:Java , Java SE