Java反射的优点

1,427 阅读3分钟

概念

对于反射,官方给出的概念:反射是Java语言的一个特性,它允许程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。说的简单点,程序在运行时动态获取类的属性和方法并调用对象称为反射,反之则是在代码中固定调用的是哪一个对象,哪一个方法。

优缺点

优点:可以实现动态创建对象和编译,体现出很大的灵活性。让用户在不需要修改代码的情况下获得新增的类的对象。
缺点:性能会影响。

Spring的IOC如何使用反射

我们都知道Spring是通过反射和工厂模式实现的IOC容器,那么为什么要用到反射? 先来看下不使用反射的工厂模式:

// 定义接口
interface fruit{
    public abstract void eat();
} 

// 接口实现类Apple和Orange
class Apple implements fruit{
     public void eat(){
         System.out.println("Apple");
     }
} 

class Orange implements fruit{
     public void eat(){
         System.out.println("Orange");
     }
}

// 工厂类
class Factory{
     public static fruit getInstance(String fruitName){
         fruit f=null;
         if("Apple".equals(fruitName)){
             f=new Apple();
         }
         if("Orange".equals(fruitName)){
             f=new Orange();
         }
         return f;
     }
}

// 运行
public class hello{
     public static void main(String[] a){
         fruit f=Factory.getInstance("Orange");
         f.eat();
     }
}

很明显,上面写法的缺点是当我们再添加一个子类的时候,就需要修改工厂类。如果我们添加太多的子类,改动就会很多。下面用反射机制实现工厂模式:

// 定义接口
interface fruit{
     public abstract void eat();
}

// 接口实现类Apple和Orange
class Apple implements fruit{
    public void eat(){
         System.out.println("Apple");
     }
}

class Orange implements fruit{
    public void eat(){
        System.out.println("Orange");
    }
}

// 工厂类
class Factory{
    public static fruit getInstance(String ClassName){
        fruit f=null;
        try{
            f=(fruit)Class.forName(ClassName).newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}

// 运行
class hello{
    public static void main(String[] a){
        // 运行的时候才知道我需要获得的是Apple实例对象
        fruit f=Factory.getInstance("Reflect.Apple");
        if(f!=null){
            f.eat();
        }
    }
}

使用了反射后,就算我们需要添加任意多个子类,工厂类都不需要修改。使用反射机制实现的工厂模式可以通过反射取得接口的实例,但是需要传入完整的包和类名。而且用户也无法知道一个接口有多少个可以使用的子类,所以我们通过属性文件的形式配置所需要的子类。

IOC的粗略解析

IOC中最基本的技术就是“反射(Reflection)”编程,通俗来讲就是根据给出的类名(字符串方式)来动态地生成对象,这种编程方式可以让对象在生成时才被决定到底是哪一种对象。只是在Spring中要生产的对象都在配置文件中给出定义,目的就是提高灵活性和可维护性。

我们可以把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言提供的反射机制,根据配置文件中给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。