反射的作用
  • 在运行时获取类的信息。如果没有反射,则需要由new创建对象,在代码里写死了,若需要使用不同的类型,就需要修改代码来,执行不同的操作。

例子1:如果有一个简单的工厂模式:

    interface Inter{
        void doSomething();
    }
    class AA implements Inter{
        @Override
        public void doSomething() {
            System.out.println("AA do something");
        }
    }
    class BB implements Inter{
        @Override
        public void doSomething() {
            System.out.println("BB do something");
        }
    }
    //简答工厂模式,获得实例化对象
    class Factory{
        public static Inter getInstance(String className){
            Inter inter = null;
            if(className.equals("AA")){
                inter = new AA();
            }else if(className.equals("BB")){
                inter = new BB();
            }
            return inter;
        }
    }
    class Test{
        public static void main(String[] args) {
           Inter inter = Factory.getInstance("BB");
            inter.doSomething();
        }
    }

在没有反射机制时,若有其他类实现了Inter接口,若要通过工厂获取该类的实例,则必须修改Factory类,不方便。

现在利用反射机制实现工厂类:

        class Factory{
        public static Inter getInstance(String className){
            Inter inter = null;
            try {
                Class ca = Class.forName(className);
                inter = (Inter) ca.newInstance();
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
            return inter;
        }
    }
    class Test{
        public static void main(String[] args) {
            Inter inter = Factory.getInstance("基础.BB");
            inter.doSomething();
        }
    }

现在无论有多少个类实现了Inter接口,我们都不需要修改工厂类。大大简化了编码。

例子2:动态代理

动态代理是用一个中间类,在不修改原有代码的基础上,做一些额外的动作,例如扩展功能或者同一接口等。

 

什么是反射?

官方的话就是:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

通俗的说就是可以不用在运行之前就确定是哪一个类,而是在运行的时候再去确定。也就是代码执行到了需要某个类的实例化对象的时候,再去找那个类的Class对象,从Class对象里获取到这个类的信息,并对它进行操作。

这里Class就是反射的基础,所有的类(包括基本数据类型和void)都有.class来获取这个Class对象。通常有3重方式获取class对象:

① 类.class;

② Class.forName(类的全限定名);

③ 对象.getClass();

例如一般通过AA aa = new AA();来床架一个对象。

利用反射则可以这样来创建对象(还是利用上边第一个例子里的类和接口):

    Class ca = Class.forName("AA");//获取AA类的class对象

    (Inter)ca.newInstance();//获取aa的一个实例

以上两句话就相当于AA aa = new AA();

这样写比直接new的好处在哪呢?

好处就是只要是实现了Inter这个接口的类,只要传入类名,就可以调用不同的子类实现。

还可以这样改:

    String className = getClassNameFromXml;

    Class ca = Class.forName(className);//获取AA类的class对象

    (Inter)ca.newInstance();//获取aa的一个实例

这样可以从xml文件读取类信息,上边的代码完全可以不用修改,有很好的扩展性。