先说一下区别
1、使用newInstance可以解耦。使用newInstance的前提是,类已加载并且这个类已连接,这是正是class的静态方法 forName()完成的工作。newInstance实际上是把new 这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。
2、newInstance: 弱类型。低效率。只能调用无参构造。 new: 强类型。相对高效。能调用任何public构造。
3、newInstance()是实现IOC、反射、面对接口编程和依赖倒置等技术方法的必然选择,new只能实现具体类的实例化,不适合于接口编程。
4、 newInstance() 一般用于动态加载类。
上代码
public class Demo {
public static void main(String[] args) {
try {
/**
* Class.forName(String):要求JVM查找并加载String指定的类
* 返回String串指定的类
*/
Class clazz = Class.forName("com.yao.test.sjmstest.Demo");
/**
* clazz.newInstance()
* 返回的类所代表的一个实例和new Demo()效果是一样的。
*/
Demo demo = (Demo) clazz.newInstance();
demo.method(demo);
//这里的demo1与上面的demo效果是一样的
Demo demo1 = new Demo();
demo1.method(demo1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public void method(Demo demo) {
System.out.println(demo);
}
}
运行结果:
com.yao.test.sjmstest.Demo@1d44bcfa
com.yao.test.sjmstest.Demo@266474c2
可见两种方法得到的对象并没有什么区别
实际应用
接口:
public interface ParentPrint {
void print(String classname);
}
子类A:
public class SonAPrint implements ParentPrint{
public void print(String classname) {
System.out.println("Clas A");
System.out.println(classname);
}
}
子类B:
public class SonBPrint implements ParentPrint {
public void print(String classname) {
System.out.println("Class B");
System.out.println(classname);
}
}
工厂类:
public class PrintFactory {
public static ParentPrint getParentPrint(Class clazz) {
try {
ParentPrint print = (ParentPrint) clazz.newInstance();
return print;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
测试类:
public class Main {
public static void main(String[] args) {
ParentPrint print = PrintFactory.getParentPrint(SonAPrint.class);
print.print("A");
ParentPrint print1 = PrintFactory.getParentPrint(SonBPrint.class);
print.print("B");
}
}
运行结果:
Clas A
A
Clas A
B