直接用 new 调用构造方法需满足类已定义、构造方法可访问且参数匹配,不可用于抽象类、接口或枚举;若自定义了带参构造,则默认无参构造消失,需显式添加;泛型中不能 new T(),因类型擦除;匿名内部类可绕过接口/抽象类限制。

直接用 new 调用构造方法即可,但必须确保类已定义、构造方法可访问、参数匹配,且不用于抽象类或接口。
构造方法必须存在且可访问
Java 中每个类至少有一个构造方法。如果没写任何构造方法,编译器会自动添加一个无参的默认构造方法;但只要写了带参构造,这个默认构造就没了。
实操建议:
- 若类只定义了
public MyClass(String name),就不能写new MyClass(),否则编译报错:Constructor MyClass() is undefined - 想支持无参实例化,就得显式加上
public MyClass() { } - 构造方法权限(
private/protected)会影响new的可用范围——跨包调用时,必须是public或合适的protected
泛型类实例化时类型擦除不影响 new 行为
new 操作本身不保留泛型信息,比如 new ArrayList<string>()</string> 在运行时就是 ArrayList,类型参数仅用于编译期检查。
立即学习“Java免费学习笔记(深入)”;
实操建议:
- 不能写
new T()(在泛型方法中),因为T已被擦除,编译不通过 - 若需运行时创建泛型对象,得传入
Class<t></t>参数,再用clazz.getDeclaredConstructor().newInstance() -
new ArrayList()(钻石语法)合法,但本质仍是调用ArrayList的无参构造,不是“泛型构造”
new 不能用于抽象类、接口、枚举(除非匿名子类)
抽象类没有完整实现,接口无具体行为,它们都不能直接 new。但可以用匿名内部类绕过限制(仅限非 final 类/接口)。
实操建议:
-
new Runnable() { public void run() { } }合法,这是创建Runnable匿名实现类的实例 -
new List<string>() { ... }</string>编译失败,因为List是接口且不能直接实例化(即使写了方法体也不行) -
new AbstractList<string>() { ... }</string>合法,前提是补全所有抽象方法(如get(int)、size()) - 枚举类的构造方法是
private,禁止外部new,只能用MyEnum.VALUE
真正容易卡住的地方,往往不是语法写错,而是没看清类是否被设计为可直接实例化——比如 Spring 的 @Service 类被代理后,手动 new 会绕过依赖注入;又比如某些工具类把构造方法设为 private,只留静态工厂方法,这时硬写 new 就会编译失败。


















