静态语句块、构造语句块和构造函数的执行顺序

本文详细解析了Java中类的构造方法、非静态代码块、静态代码块的执行顺序及原理,通过具体代码示例展示了类加载过程中的初始化流程,强调了静态与非静态成员在对象创建时的不同行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class A {
	//构造方法
	public A(){
		System.out.println("A--->父类构造方法");
	}
	//非静态代码块
	{
		System.out.println("A--->父类非静态代码块");
	}
	//静态代码块
	static{
		System.out.println("A--->父类静态代码块");;
	}

}
public class B extends A{
	//构造方法
	public B(){
		System.out.println("B--->构造方法");
	}
	//非静态语句块
	{
		System.out.println("B--->非静态语句块");
		
	}
	//静态语句块
	static{
		System.out.println("B--->静态语句块");
		
	}
	public static void main(String[] args) {
		System.out.println("----开始----");
		new B();
		System.out.println("----结束----");
	}
}

运行结果:
在这里插入图片描述

new两次

public class B extends A{
	//构造方法
	public B(){
		System.out.println("B--->构造方法");
	}
	//非静态语句块
	{
		System.out.println("B--->非静态语句块");
		
	}
	//静态语句块
	static{
		System.out.println("B--->静态语句块");
		
	}
	public static void main(String[] args) {
		System.out.println("----开始----");
		new B();
		new B();
		System.out.println("----结束----");
	}
}

运行结果:在这里插入图片描述
静态块属于类的,非静态属于对象,有对象才有类,有类不一定有对象。打个比方,有车子一定有图纸,有图纸未必有车子。静态块用于类的初始化,构造函数用于对象的初始化,所以静态块在非静态块之前执行。静态代码只在第一次new执行一次,之后不再执行,而非静态块每new一次就执行一次。
所以静态方法>非静态语句块>构造方法
在这里插入图片描述
上图是我遇到的面试题

import Test02.Test01;

public class Test01 {
	public static Test01 t1 = new  Test01();
	
	{
		System.out.print("blockA");
	}
	
	static {
		System.out.print("blockB");
		
	}
	public static void main(String[] args) {
		System.out.print("开始");
		Test01 t2 = new Test01();
		System.out.println("结束");
		
	}
}

运行结果:C,运行程序时先运行静态方法new了一个t1对象,t1里面就一个语句块,然后就打印了A,然后在执行下一个静态方法打印B,这些都在mian方法之前执行的,然后在执行main,然后打印"开始",再new t2这个对象,因为静态方法只在类加载的时候执行一次,所以就打印A,所以选C。
在这里插入图片描述

### 构造函数的使用方法与语法 构造函数是一种特殊的函数,用于初始化对象或类的实例。以下是不同编程语言中构造函数的使用方法语法: #### 1. C++ 构造函数 在C++中,构造函数用于初始化类的对象,并且可以使用初始化列表来直接初始化成员变量。语法如下: ```cpp ClassName() : member1(value1), member2(value2) { // 构造函数体 } ``` 例如,定义一个简单的 `Person` 类并使用初始化列表: ```cpp class Person { public: std::string name; int age; // 构造函数 Person(std::string n, int a) : name(n), age(a) {} // 初始化列表[^1] }; ``` #### 2. Java 构造函数 Java中的构造函数在创建对象时自动调用。通过 `new` 关键字构造函数名称(与类名相同)来创建对象。示例如下: ```java public class Person { private String name; private int age; // 无参数构造函数 public Person() {} // 带参数构造函数 public Person(String name, int age) { this.name = name; // 使用this关键字访问实例变量[^2] this.age = age; } } public class Main { public static void main(String[] args) { // 调用无参数构造函数 Person person1 = new Person(); // 调用带参数构造函数 Person person2 = new Person("Alice", 30); } } ``` #### 3. C 构造函数与析构函数 C语言本身并不支持构造函数的概念,但可以通过函数模拟类似的行为。C++继承了C的语言特性,并引入了构造函数析构函数。构造函数的调用顺序是:从最根父类到派生类依次调用[^3]。 ```cpp class Base { public: Base() { std::cout << "Base constructor" << std::endl; } }; class Derived : public Base { public: Derived() { std::cout << "Derived constructor" << std::endl; } }; int main() { Derived d; // 输出:Base constructor Derived constructor return 0; } ``` #### 4. JavaScript 构造函数 在JavaScript中,构造函数通常以大写字母开头,用于创建对象实例。当使用 `new` 关键字调用构造函数时,会创建一个新的对象实例,并将 `this` 绑定到该对象上[^4]。 ```javascript function Person(name, age) { this.name = name; // 实例成员 this.age = age; // 实例成员 } // 静态成员 Person.species = 'Homo sapiens'; var person1 = new Person('Alice', 25); // 创建实例 console.log(person1.name); // 输出:Alice console.log(Person.species); // 输出:Homo sapiens ``` #### 注意事项 - 在C++中,初始化列表比在构造函数体内赋值更高效。 - 在Java中,构造函数必须与类名相同,并且不能有返回类型[^2]。 - 在C++中,派生类的构造函数会先调用基类的构造函数[^3]。 - 在JavaScript中,构造函数内部无需显式返回对象,因为 `new` 关键字会自动处理[^4]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值