Java中newInstance()与new 比较
从功能上看,new 和 newInstance() 都能创建类的实例。前者是关键字,后者是方法。差别在于:newInstance() 走类加载机制,按运行时拿到的类名来反射创建;new 在源码里写死类型,直接创建。
为什么要两种方式?主要是软件的可伸缩、可扩展、可复用:明确知道要哪个类时用 new;类名来自配置时用 newInstance(),换实现不用改调用代码。
注意:Class.newInstance() 只能调用公共无参构造。Java 9 起该方法已过时,推荐 clazz.getDeclaredConstructor().newInstance(),能力相同,异常更明确。
| 对比 | new | newInstance() |
|---|---|---|
| 类型 | 强类型,编译期就确定类 | 弱类型,类名可以是字符串 |
| 效率 | 相对高 | 反射,相对低 |
| 构造 | 可调用任意可见构造 | Class.newInstance 只能无参构造 |
| 场景 | 明确知道要哪个类 | 工厂、配置、插件式替换实现 |
一、工厂模式里为什么用 newInstance
Java 工厂经常用反射创建对象。变量类型写成父类或接口,运行时 new 出来的是具体实现,调用方不必改。
ExampleInterface 是 Example 实现的接口。类名还可以抽成变量:
再进一步,类名从 XML 配置读:
这段代码里已经没有 Example 这个类名。Example 怎么改、甚至换成 Example2、Example3,只要它们实现 ExampleInterface,上面几行都不用动。返回的永远是接口类型,不是某个写死的子类。
二、从 JVM 看:newInstance 把 new 拆成两步
用关键字 new 时,这个类当时还没加载也可以,虚拟机会顺带加载。用 newInstance() 则必须保证:类已经加载,并且已经连接。这两步正是 Class.forName() 做的。
所以 newInstance() 相当于把 new 拆开:先 forName 加载某个类,再实例化。分步的好处是:加载哪一个类可以放到运行时决定,调用点和具体实现解耦。
三、怎么选
明确知道自己要什么,直接 new。类名从配置加载、希望换实现不改源码,用 newInstance(或构造器上的 newInstance)。
一句话总结:new 强类型、高效、能调任意构造;newInstance 弱类型、靠反射和配置换实现,只能走无参构造。
转载请注明来源:Java中newInstance()与new 比较







