JAVA学习——静态代码块、构造代码块、构造器、普通代码块的执行顺序

概念

在此之前,我们先来看看JAVA中的这些代码块:

  • 静态代码块

在类中使用static修饰,并使用"{}"括起来的代码片段。用于静态变量的初始化或对象创建前的环境初始化。

  • 构造代码块

在类中没与任何的前缀或后缀,并使用"{}"括起来的代码片段。

  • 普通代码块

就是在方法后面使用"{}"括起来的代码片段,不能单独执行,必须用其方法名调用才可以执行。

  • 同步代码块

使用synchronize关键字修饰,并使用"{}"括起来的代码片段。

表示在同一时间只能有一个线程进入到该方法块中,是一种多线程保护机制。

实例

代码

public class Code {

	// 静态代码块
	static {
		System.out.println("我是静态代码块");
	}

	// 构造代码块
	{
		System.out.println("我是构造代码块");
	}

	// 无参构造方法(构造器)(方法名与类名必须一致,返回值类型就是类本身,无需写)
	public Code() {
		System.out.println("我是无参构造方法");
	}

	// 普通代码块,必须要有返回值类型
	public void Code1() {
		System.out.println("我是普通代码块");
	}

	public static void main(String[] args) {

		Code c1 = new Code();
		Code c2 = new Code();

		c1.Code1();
		c2.Code1();
	}
}

结果

理解了上面的结果之后,问题来了,我们都知道代码块没有独立执行的能力,
构造器(构造方法)是通过关键词new来调用执行,
普通代码块通过方法名调用执行,
那编译器是如何处理构造代码块的?

实际上,很简单,编译器会把构造代码块插入到每个构造函数的最前端。相当于:

// 无参构造方法(构造器)(构造器返回值类型就是类本身,无需写)
public Code() {
	System.out.println("我是构造代码块");
	System.out.println("我是无参构造方法");
}

这样,自然在通过new关键字生成一个实例的时侯会先执行构造代码块,然后再执行其他代码(注意:构造代码块不是在构造函数之前运行,而是依托于构造函数)

这就有了构造代码块的两个主要应用场景:

1. 初始化实例变量

如果每个构造函数都需要初始化变量,就可以通过构造代码块来实现,从而取代在每个构造函数中都去调用初始化实例变量的方法。

2. 初始化实例环境

一个对象必须在适当的场景下才能存在,如果没有适当的场景,则就需要在创建对象的时候创建此场景。如构造代码块

这两个场景就是利用了构造代码块的两个特性:

1. 在每个构造函数中都运行

2. 在构造函数中它会首先运行

构造代码块的出现就是为了提取构造函数的共同量,降低各个构造函数的代码重复度。如下:

public class Code {

	public static int count = 0;

	{
		count++;
	}

	public Code() {
	}

	public Code(int i) {

		// this()调用,增强代码的复用。
		this();
	}

	public Code(String string) {
	}

	public static void main(String[] args) {
		new Code();
		new Code(1);
		new Code("1");
		System.out.println(Code.count);
	}
}

结果为3

拓展

对于有继承的类来说,其中顺序又是如何的呢?

更为深入地说,

1。方法 

  • 首先,不管是静态方法还是非静态方法,都需要调用后执行;
  • 其执行的次序和在类里声明的次序无关;
  • 区别是静态方法是“class.method"方式执行,非静态方法是"object.method"方式执行,即后者需要创建一个对象。

2。变量

  • 静态成员变量(也称类变量)先于非静态成员变量初始化,
  • 静态成员变量在类第一次加载时初始化,所有对象共享一份静态成员变量,非静态成员变量则在对象创建时初始化。

关于类的加载:

类只加载一次,还是懒加载的,只在第一次调用该类时加载(如new该类的对象时、调用该类的Static方法或者变量时)。

换个角度说,对于java虚拟机来说,它的机器码就是.class文件。
每个.class文件被加载,就会在内存中产生一个Class对象,一个类(.class)文件对应着一个Class对象。
这个Class对象类似于模板,在第一次调用该类时被创建并加载到java虚拟机,用于创建该类的对象。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值