Java中newInstance()与new 比较

    |     2015年3月30日   |   Java面向对象高级特性   |     0 条评论   |    1627

从功能上看,new 和 newInstance() 都能创建类的实例。前者是关键字,后者是方法。差别在于:newInstance() 走类加载机制,按运行时拿到的类名来反射创建;new 在源码里写死类型,直接创建。

为什么要两种方式?主要是软件的可伸缩、可扩展、可复用:明确知道要哪个类时用 new;类名来自配置时用 newInstance(),换实现不用改调用代码。

注意:Class.newInstance() 只能调用公共无参构造。Java 9 起该方法已过时,推荐 clazz.getDeclaredConstructor().newInstance(),能力相同,异常更明确。

对比 new newInstance()
类型 强类型,编译期就确定类 弱类型,类名可以是字符串
效率 相对高 反射,相对低
构造 可调用任意可见构造 Class.newInstance 只能无参构造
场景 明确知道要哪个类 工厂、配置、插件式替换实现

一、工厂模式里为什么用 newInstance

Java 工厂经常用反射创建对象。变量类型写成父类或接口,运行时 new 出来的是具体实现,调用方不必改。

Class c = Class.forName("Example");
factory = (ExampleInterface) c.newInstance();

ExampleInterface 是 Example 实现的接口。类名还可以抽成变量:

String className = "Example";
Class c = Class.forName(className);
factory = (ExampleInterface) c.newInstance();

再进一步,类名从 XML 配置读:

String className = readfromXMlConfig; // 从 xml 配置文件中获得字符串
Class c = Class.forName(className);
factory = (ExampleInterface) c.newInstance();

这段代码里已经没有 Example 这个类名。Example 怎么改、甚至换成 Example2、Example3,只要它们实现 ExampleInterface,上面几行都不用动。返回的永远是接口类型,不是某个写死的子类。

二、从 JVM 看:newInstance 把 new 拆成两步

用关键字 new 时,这个类当时还没加载也可以,虚拟机会顺带加载。用 newInstance() 则必须保证:类已经加载,并且已经连接。这两步正是 Class.forName() 做的。

所以 newInstance() 相当于把 new 拆开:先 forName 加载某个类,再实例化。分步的好处是:加载哪一个类可以放到运行时决定,调用点和具体实现解耦。

三、怎么选

明确知道自己要什么,直接 new。类名从配置加载、希望换实现不改源码,用 newInstance(或构造器上的 newInstance)。

一句话总结:new 强类型、高效、能调任意构造;newInstance 弱类型、靠反射和配置换实现,只能走无参构造。

转载请注明来源:Java中newInstance()与new 比较
本文链接地址:https://ai.zhousir.top/?p=109

上一篇:

下一篇:

回复 取消