父类、子类静态代码块加载的问题

那_年 2016-10-29 05:06:16
我遇到了和论坛网友同样的问题,子类加载时,首先会加载父类的静态变量、静态块、静态方法,然后再加载子类的静态变量、静态块、静态方法,但是有时候,子类的静态块被跳过了。虽然看了之前那位网友的跟帖解释,但还是不解,所以发帖求助!

我的代码:
public class Jiazaishunxu {
public static void main(String[] args){
System.out.println(Zi.a);
}
}

class Fu{
static int a=1;
int b=2;
static{
System.out.println("父类静态代码块:"+a);
}
}

class Zi extends Fu{
static{
System.out.println("子类静态代码块:"+a);
}
}


输出结果:
父类静态代码块:1
1

为什么子类的静态代码块没有执行?很是不解,于是又用了下面的方法进行测试。
public class Jiazaishunxu {
public static void main(String[] args){
System.out.println(Zi.a);
}
}

class Fu{
static int a=1;
int b=2;
static{
System.out.println("父类静态代码块:"+a);
}
}

class Zi extends Fu{
static int a=3;
static{
System.out.println("子类静态代码块:"+a);
}
}


输出结果:
父类静态代码块:1
子类静态代码块:3
3

这次结果输出正常了。

上面两种结果,完全不能理解。还望前辈们指点~

这是之前hubeihuyang发的提问帖。
http://bbs.csdn.net/topics/390636568?page=1
...全文
267 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
NewMoons 2016-10-30
  • 打赏
  • 举报
回复
说实话对于我这种老鸟,第一反应也做错了。 虽然现在很少去研究这些东西了,但还是为你这种钻研精神点赞。 你的总结我没细看(因为太多),但应该是对的。 我觉得可以用一句话总结:因为虚拟机jvm觉得你的代码运行不依赖子类的任何东西,所以没有必要调用子类得任何代码。
那_年 2016-10-30
  • 打赏
  • 举报
回复
谢谢楼上回答,我自己写了代码模拟了下,自己总结了如下经验,分享给大家,还请多多指正 1、子类静态代码块运行的条件:第一种:使用了new创建子类对象。第二种,子类的静态方法或者静态成员变量调用,如果子类中存在重载的静态成员变量或者静态方法,且在静态调用时用到,会运行子类中所有静态函数、静态块 2、使用new创建对象时,会按顺序执行父类静态成员赋值、静态代码块,子类的静态成员赋值、静态代码块,普通成员变量赋值,构造代码块,构造函数 3、new的作用:成员赋值。构造函数。

package test;
//为什么子类的静态代码块有时候不加载


public class Jiazaishunxu {
	public static void main(String[] args){
		
//		Zi.fun0();
//		System.out.println("***********");
//		Fu.fun0();
//		System.out.println("***********");
//		System.out.println(Zi.a);
//		System.out.println("***********");
//		System.out.println(Fu.a);
//		System.out.println("***********");
//		new Zi();

		System.out.println(Fu.a);
		System.out.println("***********");
		
		System.out.println(Zi.a);		
		System.out.println("***********");
		
		Fu.fun0();
		System.out.println("***********");
		
		Zi.fun0();
		System.out.println("***********");
		
		new Zi().fun();
		
	}
}

class Fu{
	static int a=1;
	int b=2;
	static{
		System.out.println("父类静态代码块:"+a);
	}
	static void fun0(){
		System.out.println("父类静态方法");
	}
	void fun(){
		System.out.println("父类方法:"+a);
	}
	Fu(){
		System.out.println("b:"+b);
	}
}

class Zi extends Fu{
//	static int a;
	static{
		int b=0;
		System.out.println("子类静态代码块:"+a);
		System.out.println("子类静态代码块:"+b);
	}
	static void fun0(){
	
}
	static{
		System.out.println("子类静态代码块2:");
	}
	void fun(){
		System.out.println("子类方法:"+a);
	}
}

执行结果: 父类静态代码块:1 1 *********** 1 *********** 父类静态方法 *********** 子类静态代码块:1 子类静态代码块:0 子类静态代码块2: *********** b:2 子类方法:1
gtchendong 2016-10-29
  • 打赏
  • 举报
回复
因为你主函数里Zi.a,那个成员变量a是在父类中的,所以java虚拟机认为没必要加载Zi类,因为Zi类中的函数没有被用到,你想深入了解java虚拟机的话,可以去找找相关书籍,仔细看看

62,614

社区成员

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

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