当拿到一个类的时候,肯定要直接使用关键字new进行对象实例化操作,但是如果有了Class类对象,那么就可以做到,利用反射来实现对象实例化操作。
Class类中的实例化对象方法:
public T newInstance()
throws InstantiationException,
IllegalAccessException
范例:利用反射实例化对象(实例化Book类对象)
public static void main(String[] args) throws Exception{
Class <?> cls=Class.forName("TestDemo.Book");//取得Book类
Object obj=cls.newInstance();//取得Book类实例化对象 相当于使用new调用无参构造实例化
System.out.println(obj);
}
image.png
有了反射之后,以后进行对象实例化的操作不再是单独依靠关键字new,反射也可以完成。
在任何的开发之中,new是造成耦合的最大元凶,一切的耦合都起源于new,为了完成高内聚,低耦合,Spring,SpringMVC都内置了反射。
范例:观察我们原先的工厂设计模式
package TestDemo;
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
System.out.println("eat apple");
}
}
class Factory{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple();
}
return null;
}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Fruit f=Factory.getInstance("apple");
f.eat();
}
}
如果此时增加了Fruit接口子类,那么就表示程序要修改工厂类,每增加一个类就要取修改工厂类,那么如果随时可能增加子类,那么工厂类就要一直进行修改,因为工厂类中的对象都是通过new直接实例化的,而new就成了所有问题的关键点。要想解决这一问题,就只能够依靠反射完成。
package TestDemo;
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
System.out.println("eat apple");
}
}
class Orange implements Fruit{
@Override
public void eat() {
System.out.println("eat orange");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit f=null;
try {
f=(Fruit)Class.forName(className).newInstance();//根据传入参入进行子类实例化获取
} catch (Exception e) {
//TODO: handle exception
}
return f;
}
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Fruit f=Factory.getInstance("TestDemo.Apple");
f.eat();
}
}
这样就不需要修改工厂类,程序完成了解耦和的目的,并且可扩展性非常强。
网友评论