从类文件分析Java类装载过程<clinit>方法的调用和<init>的调用

本文分析了Java类的装载过程,从执行开始,详细阐述了类加载的各个阶段,包括静态成员变量的初始化、成员变量的存储以及<clinit>和<init>方法的调用顺序。在类初始化时,系统首先执行<clinit>方法,确保父类的静态初始化完成,然后执行成员变量初始化和构造方法。
摘要由CSDN通过智能技术生成

从Java执行过程开始

由于在eclipse中编写Java代码很容易忽视Java的运行流程,eclipse会自动编译源文件,屏蔽掉了生成字节码的过程,所以很容易忽视对于类的加载和运行的过程。
当在父类的构造方法中调用了子类的方法时,子类中成员变量初始化出错,代码如下:
class Print{
	Print(String s){
		System.out.println("Step "+s);
	}
	Print(String s,double i){
		System.out.println("Step "+s+"  随机数 "+i);
	}
}

abstract class Glyph {
	abstract void draw();
	Print p2 = new Print("父类成员变量");
	static Print p3= new Print("父类静态成员变量");
	static Print p6= new Print("父类静态成员变量",Math.random());
	Glyph() {
		System.out.println("父类构造方法");
		System.out.println("Glyph() before draw()");
		draw(); 
		System.out.println("Glyph() after draw()");
	}
}

class RoundGlyph extends Glyph {
      int radius = 1;
      String s = "abcdefg";
	  static Print p4= new Print("子类静态成员变量");
	  static Print p5= new Print("子类静态成员变量",Math.random());
	  Print p1 = new Print("子类成员变量");
	  RoundGlyph(int r) {
		  System.out.println("子类构造方法");
		  radius = r;
		  System.out.println(
	      "RoundGlyph.RoundGlyph(), radius = "
	      + radius);
	  }
	  void draw() { 
		  System.out.println("子类draw方法, radius = " + radius+" 字符串 "+s);
	  }
}

public class PolyConstructors {
	public static void main(String[] args) {
		new RoundGlyph(5);
	}
}

运行结果如下:

Step 父类静态成员变量
Step 父类静态成员变量  随机数 0.8817076586261154
Step 子类静态成员变量
Step 子类静态成员变量  随机数 0.937529828526132

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值