Java 静态语句块、语句块、构造函数

本文详细解析了一段Java程序的执行流程,包括静态语句块、语句块以及构造函数的执行顺序。通过分析代码实例,阐述了对象初始化的过程,包括静态代码块、非静态代码块和构造方法的执行顺序,并解释了子类构造方法如何调用父类构造方法的机制。

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

以下是一道笔试题:
package com.example;

public class Parent
{
public Parent()
{
System.out.println("Parent>>>>>>>>>>>1");
}

{
System.out.println("Parent>>>>>>>>>>>2");
}
static
{
System.out.println("Parent>>>>>>>>>>>3");
}
}

package com.example;

public class Child extends Parent
{
public Child()
{
System.out.println("Child>>>>>>>>>>>1");
}

{
System.out.println("Child>>>>>>>>>>>2");
}
static
{
System.out.println("Child>>>>>>>>>>>3");
}

public static void main(String[] args)
{
new Child();
}
}

请写出上面程序的执行结果。


此题是考查静态语句块、语句块以及构造函数的执行顺序。

分析:对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
而且子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。


因此执行结果是:
Parent>>>>>>>>>>>3
Child>>>>>>>>>>>3
Parent>>>>>>>>>>>2
Parent>>>>>>>>>>>1
Child>>>>>>>>>>>2
Child>>>>>>>>>>>1
### 构造函数的使用方法与语法 构造函数是一种特殊的函数,用于初始化对象或类的实例。以下是不同编程语言中构造函数的使用方法和语法: #### 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、付费专栏及课程。

余额充值