类加载

tp30512kuang 2011-12-18 12:52:30

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);
}
}

[Quote]
初始化是类加载的一个步骤,但这个类为什么在被java.exe运行后,在控制台输出了
---------------- 之后才进入ClassLoader类呢?

单步执行Test_1_2后在显式赋值的static成员变量及静态初始化块中的变量语句和输出语句处均会
暂停,直到遇到main方法后直接跳至类声明行”public class Test_1_2 {“处暂停,
然后一个stepInto直接跑到ClassLoader中,那么在这次执行过程中这是不是首次进入的
ClassLoader呢?

如果是的话前面静态成员的初始化不需要ClassLoader么?
[/Quote]
...全文
124 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jaya1989 2011-12-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wangfeiwoyun 的回复:]

简单解释一下:
当你运行java Test_1_2的时候,实际是执行Test_1_2.main(), 当虚拟机启动某个被表明为启动类的类(即含有main方法的那个类)这是一种主动引用。JVM规定了几种主动引用(看这里:JVM Specification - 5.5 Initialization,点这里下载Java 7 版)。
在这种情况下,虚拟机要先初始化这个类。但初始化前先要load,然后……
[/Quote]
是这样的。
zysnba 2011-12-19
  • 打赏
  • 举报
回复
static 这个修饰的话是成员变量,当类加载的时候,所有的static都会被加载,然后在进main方法
龙四 2011-12-19
  • 打赏
  • 举报
回复
简单的解释:

1、java编译后将所有的static(包括static块,static变量)按顺序全部弄到一个方法里,这个方法叫做<clinit>

2、类load的步骤:装载-连接(验证-准备-解析)-初始化(此时执行<clinit>方法),只有初始化了的类才能使用
dmowker 2011-12-19
  • 打赏
  • 举报
回复
正解,是在ClassLoader之后执行静态块的

[Quote=引用 3 楼 smcwwh 的回复:]

引用 2 楼 tp30512kuang 的回复:

引用 1 楼 h43857892 的回复:

静态块的方法是最先执行的,所以会输出--------,然后执行main方法 输入6
谢谢关注撒 不过我想问的是用java.exe执行主类后ClassLoader是在输出--------之前
还是之后才执行的呢? 也许debug并不反映底层真实加载情况,但debug一下会发现
已经输出了……
[/Quote]


----------------------
http://www.lunwenwa.com/
wangfeiwoyun 2011-12-18
  • 打赏
  • 举报
回复
简单解释一下:
当你运行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。
kouyiSC 2011-12-18
  • 打赏
  • 举报
回复
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);
}
}

Jaya1989 2011-12-18
  • 打赏
  • 举报
回复
先把手头上的事情完成,
再好好看看,why。。。。
Jaya1989 2011-12-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 tp30512kuang 的回复:]

引用 1 楼 h43857892 的回复:

静态块的方法是最先执行的,所以会输出--------,然后执行main方法 输入6
谢谢关注撒 不过我想问的是用java.exe执行主类后ClassLoader是在输出--------之前
还是之后才执行的呢? 也许debug并不反映底层真实加载情况,但debug一下会发现
已经输出了--------后才进入ClassLoader ,难道说……
[/Quote]
在初始化static块之前,是有先调用ClassLoader的loadClass方法加载类的,你下载一份源码,断点到Launcher$AppClassLoader.loadClass方法。在初始化static块,打印--------以前,是有进入这个方法,加载类的。
tp30512kuang 2011-12-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 h43857892 的回复:]

静态块的方法是最先执行的,所以会输出--------,然后执行main方法 输入6
[/Quote]谢谢关注撒 不过我想问的是用java.exe执行主类后ClassLoader是在输出--------之前
还是之后才执行的呢? 也许debug并不反映底层真实加载情况,但debug一下会发现
已经输出了--------后才进入ClassLoader ,难道说加载中的初始化静态成员部分不需要
类加载器参与吗? 希望我表述清楚了 期待了解的朋友稍微指点一下
h43857892 2011-12-18
  • 打赏
  • 举报
回复
静态块的方法是最先执行的,所以会输出--------,然后执行main方法 输入6

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧