Java new一个类时并不会默认调用main函数

本文解析了Java中main函数的作用及执行原理,强调其作为程序入口的重要性,并通过实例说明了main函数与类中其他方法的关系,以及在多线程环境下main函数的执行特性。

main函数的作用只是作为一个入口
使Java虚拟机知道从哪里执行
在这里插入图片描述
在这里插入图片描述
Java Virtual Machine Specification

一旦程序启动main便成为类中一个普通的方法
不调用不执行

这时再new main函数所在类便不会执行main函数,只会执行构造方法

例1

class kk  {
	public kk() {
		System.out.println("First");
	}
	public static void main(String[] args) {
		new kk();		
	}
}

在这里插入图片描述
如果new kk类时默认执行main函数那么就会循环产生First,而不是只产生一个

例2

class kk extends Thread {

	public static void main(String[] args) {
		
		Thread threadNew1 = new kk();// 创建线程
		Thread threadNew2 = new kk();// 创建线程
		threadNew1.start();// 调用线程的strt()方法启动线程
		threadNew2.start();
				
		while(true) {
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName);
		}
		
	}

	@Override
	public void run() {
		while(true) {
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName);
		}
	}
}

本段代码new main函数所在的类,但是并没有使线程越来越多,因为main函数仅执行了一次

<think>我们正在讨论Java中实例化子构造函数调用机制。根据引用内容,我们可以总结如下: 1. 在Java中,当实例化子,一定会调用的构造函数。 2. 调用方式有两种:隐式调用(当父有无参构造函数,子构造函数默认第一行有super())和显式调用(使用super(...)指定调用的某个构造函数)。 3. 如果父没有无参构造函数,那么子必须在构造函数的第一个语句显式调用的某个构造函数,否则会编译错误。 4. 调用顺序:先调用的构造函数(从最顶层的父开始,逐层向下),然后才执行构造函数的剩余部分。 此外,引用[4]中的示例代码展示了实例化子执行顺序: - 父静态代码块(如果父有静态块) - 子静态代码块(如果子有静态块) - 父构造函数 - 子构造函数 注意:静态代码块只在加载执行一次,而构造函数在每次实例化都会执行。 因此,回答用户的问题:是的,Java实例化子一定会调用的构造函数且这个调用是自动发生的(隐式或显式),以确保父部分被正确初始化。 下面我们详细解释:</think>### Java实例化构造函数调用机制详解 在 Java 中,**实例化子必定会调用的构造函数**,这是 Java 继承机制的核心规则。具体机制如下: #### 1. 调用规则 - **隐式调用**:当父存在**无参构造函数**,子构造函数会**自动调用**父无参构造(编译器自动添加 `super()`) ```java class Parent { Parent() { System.out.println("父构造"); } // 无参构造 } class Child extends Parent { Child() { // 编译器自动添加 super(); System.out.println("子构造"); } } ``` **输出**: ``` 父构造 子构造 ``` - **显式调用**:当父**没有无参构造**,子**必须显式调用**父有参构造(`super(参数)`) ```java class Parent { Parent(String s) { System.out.println("父构造:" + s); } } class Child extends Parent { Child() { super("显式调用"); // 必须显式调用 System.out.println("子构造"); } } ``` #### 2. 调用顺序 1. **静态初始化**(加载执行一次) - 父静态代码块 → 子静态代码块 2. **实例初始化**(每次实例化执行) - 父成员变量初始化 → 父构造 → 子成员变量初始化 → 子构造 ```java class Parent { static { System.out.println("父静态块"); } Parent() { System.out.println("父构造"); } } class Child extends Parent { static { System.out.println("子静态块"); } Child() { System.out.println("子构造"); } } ``` **实例化输出**: ``` 父静态块 // 首次加载执行静态块 // 首次加载执行构造 // 每次实例化 子构造 // 每次实例化 ``` #### 3. 关键限制 - **必须第一语句**:`super()` 或 `this()` 必须是构造函数的第一条语句 ```java class Child extends Parent { Child() { System.out.println("错误"); // 编译错误!super()必须在第一行 super(); } } ``` - **不可继承构造**:子不能继承父构造函数,只能调用 - **私有构造限制**:若父构造为 `private`,则无法被继承(子无法调用) #### 4. 设计原理 Java 强制调用构造是为了保证**继承链的完整性**: 1. 确保父成员正确初始化 2. 防止子方法使用未初始化的父字段 3. 维护对象状态一致性(从顶级父到最底层子) > **示例验证**(引用[4]): > ```java > public class Test { > public static void main(String[] args) { > Atest obj = new Btest(); > // 输出: 父静态 → 子静态 → 父构造 → 子构造 > } > } > ``` ### 总结 | 场景 | 调用方式 | 是否必须 | |--------------------------|----------------|----------| | 父有无参构造 | 隐式 `super()` | 自动 | | 父只有有参构造 | 显式 `super(参数)` | 强制 | | 父构造为 `private` | 无法调用 | 不可继承 | **本质**:子通过调用构造完成"从泛化到具体"的初始化过程,这是 Java 继承安全性的基石[^1][^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值