是的,完全合法且常见:main方法虽为静态入口,但可在其中安全创建其宿主类的实例,用于调用非静态成员;这不会导致无限递归,因对象创建仅发生在运行时显式执行new时。
是的,完全合法且常见:`main`方法虽为静态入口,但可在其中安全创建其宿主类的实例,用于调用非静态成员;这不会导致无限递归,因对象创建仅发生在运行时显式执行`new`时。
在Java中,public static void main(String[] args) 是JVM启动程序的唯一约定入口点。它必须是public(供JVM跨包调用)、static(无需实例即可加载执行),且参数签名严格固定。但这些约束仅作用于方法本身,并不禁止你在main内部以常规方式创建对象——包括创建其所在类自身的实例。
你提供的代码正是典型且推荐的实践:
public class Main {
void something() {
System.out.println("Works?");
}
public static void main(String[] args) {
Main m = new Main(); // ✅ 合法:在main中创建本类实例
m.something(); // ✅ 合法:通过实例调用非静态方法
}
}
✅ 为什么不会无限循环?
class Main { ... } 的定义只是编译期的类型声明,不触发任何对象创建;new Main() 是运行时的显式指令,仅在main被执行到该行时才发生一次。即使something()内部再写new Main(),也仅按逻辑执行——是否递归取决于你的代码逻辑,而非语法限制。
✅ 为什么能访问非静态成员?
main是静态方法,无法直接访问this或非静态字段/方法。但一旦通过new Main()获得实例引用(如m),就可通过该引用正常调用所有实例成员——这正是面向对象“通过对象使用行为”的核心机制。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
⚠️ 需注意的关键边界:
- 若在静态上下文(如static字段初始化、static代码块)中无条件new Main(),且该操作又间接触发同类静态初始化,则可能引发ExceptionInInitializerError(静态初始化死锁),但main方法本身不在静态初始化阶段执行,故无此风险;
- 对于非静态内部类,main中不能直接new InnerClass(),必须先有外部类实例:new Main().new InnerClass();
- main中的对象是局部变量,生命周期仅限于main方法栈帧;若需跨方法共享,应提升为类成员(注意线程安全)或通过参数传递。
? 进阶提示:这种模式广泛用于快速验证、教学示例及轻量级工具类。许多框架(如Spring Boot)的启动类也采用类似结构——main中构建ApplicationContext并启动服务,本质上仍是“静态入口 → 创建核心对象 → 委托给对象驱动运行”。
总结:在main中创建其宿主类的对象,不是语法巧合,而是Java面向对象设计与JVM启动机制协同工作的自然体现。它既满足了静态入口的启动需求,又无缝衔接到真正的OOP运行时世界。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










