请选择 进入手机版 | 继续访问电脑版
本站特色:极好的技术研究氛围!所有技术发帖,必有回复! 做最受欢迎的Java论坛

疯狂Java联盟

 找回密码
 加入联盟
查看: 41|回复: 5

类的加载问题?

[复制链接]
发表于 4 天前 | 显示全部楼层 |阅读模式
论坛的大神们,有个问题困扰着我,具体看代码:
  1. package ploymophic;

  2. public class Instance {
  3.     {
  4.         a = 6;
  5.     }
  6.     int a = 9;

  7.     public static void main(String[] args) {
  8.         System.out.println(new Instance().a);
  9.     }
  10. }
复制代码
类初始化时代码块和成员变量的优先级是相同的,谁在前先执行谁。那么a=6时,a这个变量还没声明啊,怎么会不报错?我javap查看后发现int a跑到了第一行,查资料有说非静态的这些在类加载时会被linit合并,静态的被clinit合并,是否是因为这个?
Snipaste_2018-04-16_21-14-54.png
发表于 3 天前 | 显示全部楼层
仔细看《疯狂java讲义》5.9节。
首先这里说法有个问题,这个代码块是实例初始化(不是类初始化块,类初始化块有static修饰)。
其次,实例初始化块是假象,编译之后其实是被还原到构造器中的 。
再次,定义实例变量时所赋的初始值也是假象,其实也被还原成构造器中的一条赋值语句。
也就是说,假如你在源代码中写
private int a = 6;
经过编译之后,其实这条代码变成了2条。
private int a;
另外一条 a = 6;是在构造器中执行的。
 楼主| 发表于 3 天前 | 显示全部楼层
kongyeeku 发表于 2018-4-17 04:19
仔细看《疯狂java讲义》5.9节。
首先这里说法有个问题,这个代码块是实例初始化(不是类初始化块,类初始化 ...

还不是很明白,按你所说a=6和a=9其实都是在构造器中执行的,是不是意味对于int a这个声明是被提取到构造器之前执行了?不然构造器用的话岂不要出错?
还有,那章还有个例子,是两个地方都加上static,变成类初始化块和类变量后,与构造器又有什么关系?
发表于 3 天前 | 显示全部楼层
1. 对。 int a;这条代码是在构造器之外的。
2. 类变量与构造器没有关系。
 楼主| 发表于 3 天前 | 显示全部楼层
kongyeeku 发表于 2018-4-17 12:51
1. 对。 int a;这条代码是在构造器之外的。
2. 类变量与构造器没有关系。

那么在这个代码中,与int a被提到构造器之前类似的,static int a因为某种原因提到前面先执行,然后再赋值6和6?是什么进行了这种“提前”呢?
  1. static{
  2.     a=9;

  3. static int a=6;
复制代码
发表于 3 天前 | 显示全部楼层
对。你在程序中写的这个代码也是假象。编译后之后会变成:
static int a;
static{
    a=9;
    a = 6;

重点:定义类变量时所指定的初始值是假象,编译之后会变成类初始化块中一条赋值语句。
您需要登录后才可以回帖 登录 | 加入联盟

本版积分规则

小黑屋|手机版|Archiver|疯狂Java联盟 ( 粤ICP备11063141号 )

GMT+8, 2018-4-20 14:46 , Processed in 0.298244 second(s), 7 queries , File On.

快速回复 返回顶部 返回列表