一、Java反射机制概述

Java放射机制是指在==运行状态==中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性;这种动态获取信息及动态调用方法的功能成为Java的反射机制

二、反射的作用

  1. 利用Java机制,在Java程序中可以动态的去调用一些protected甚至是private的方法或类,这样就可以在很大程度上满足一些特殊需求。
  2. Android SDK的源码中,很多类或方法中经常加上了“@hide”注释标记,它的作用是使这个方法或类在生成SDK时不可见,所以程序可能无法编译通过,而且在最终发布的时候,就可能存在一些问题。对于这种问题,第一种方法就是自己去掉源码中的“@hide”标记,然后在重新编译生成一个SDK。另一种方法就是使用Java反射机制,利用反射机制可以访问存在访问权限的方法或修改其访问域。
  3. 可能有人会有疑问,明明直接new对象就好了,为什么非要用反射呢?代码量不是反而增加了?其实反射的初衷不是方便你去创建一个对象,而是让你在写代码的时候可以更加灵活,降低耦合,提高代码的自适应能力。

怎么样降低耦合度,提高代码的自适应能力?

通过接口实现,但是接口如果需要用到new关键字,这时候耦合问题又会出现

举个例子:


/**
/**
 * @ClassName: TestReflection 
 * @Model : (所属模块名称)
 * @Description: 使用反射降低耦合度(通过接口来实现)
 * @author Administrator 
 * @date 2017年6月2日 下午5:09:38 
 */
public class TestReflection {

    /**
    /**
     * main (这里用一句话描述这个方法的作用) 
     * @param args
     * void 
     * @ModifiedPerson Administrator
     * @date 2017年6月2日 下午5:09:38 
     */
    public static void main(String[] args) {

        //普通写法,使用New 关键字
        ITest iTest = createITest("ITestImpl1");
        iTest.testReflect();
        ITest iTest2 = createITest("ITestImpl2");
        iTest2.testReflect();
        
    }

    /**
    * createITest 普通写法,使用New关键字,但是假设有1000个不同ITest需要创建,那你打算写1000个 if语句来返回不同的ITest对象?
    * @param name
    * @return
    * ITest 
    * @ModifiedPerson Administrator
    * @date 2017年6月2日 下午5:32:21
     */
    public static ITest createITest(String name){
        
        if (name.equals("ITestImpl1")) {
            return new ITestImpl1();
        } else if(name.equals("ITestImpl2")){
            return new ITestImpl2();
        }
    
        return null;
    }

}


interface ITest{
    public void testReflect();
}

class ITestImpl1 implements ITest{

    /* (non-Javadoc)
    * <p>Title: test</p> 
    * <p>Description: </p>  
    * @see ITest#test()
    */
    @Override
    public void testReflect() {

         System.out.println("I am ITestImpl1 !");
    }
}

class ITestImpl2 implements ITest{

    /* (non-Javadoc)
    * <p>Title: testReflect</p> 
    * <p>Description: </p>  
    * @see ITest#testReflect()
    */
    @Override
    public void testReflect() {

        System.out.println("I am ITestImpl2 !");
    }
    
}


假设有1000个不同ITest需要创建,那你打算写1000个 if语句来返回不同的ITest对象?

如果使用反射机制呢?


/**
/**
 * @ClassName: TestReflection 
 * @Model : (所属模块名称)
 * @Description: 使用反射降低耦合度(通过接口来实现)
 * @author Administrator 
 * @date 2017年6月2日 下午5:09:38 
 */
public class TestReflection {

    /**
    /**
     * main (这里用一句话描述这个方法的作用) 
     * @param args
     * void 
     * @ModifiedPerson Administrator
     * @date 2017年6月2日 下午5:09:38 
     */
    public static void main(String[] args) {
        //普通写法,使用New 关键字
        ITest iTest = createITest("ITestImpl1");
        iTest.testReflect();
        ITest iTest2 = createITest("ITestImpl2");
        iTest2.testReflect();
        
        //使用反射机制
        ITest iTest3 = createITest2("ITestImpl1");
        iTest3.testReflect();
        ITest iTest4 = createITest2("ITestImpl2");
        iTest4.testReflect();
        
    }

    /**
    * createITest 普通写法,使用New关键字,但是假设有1000个不同ITest需要创建,那你打算写1000个 if语句来返回不同的ITest对象?
    * @param name
    * @return
    * ITest 
    * @ModifiedPerson Administrator
    * @date 2017年6月2日 下午5:32:21
     */
    public static ITest createITest(String name){
        
        if (name.equals("ITestImpl1")) {
            return new ITestImpl1();
        } else if(name.equals("ITestImpl2")){
            return new ITestImpl2();
        }
    
        return null;
    }
    
    /**
    * createITest2 使用反射机制:当有1000个不同ITest需要创建时,不用针对每个创建ITest对象
    * @param name
    * @return
    * ITest 
    * @ModifiedPerson Administrator
    * @date 2017年6月2日 下午5:34:55
     */
    public static ITest createITest2(String name){
        try {
            Class<?> class1 = Class.forName(name);
            ITest iTest = (ITest) class1.newInstance();
            return iTest;
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
        } catch (InstantiationException e) {

            e.printStackTrace();
        } catch (IllegalAccessException e) {

            e.printStackTrace();
        }
        
        return null;
        
    }

}


interface ITest{
    public void testReflect();
}

class ITestImpl1 implements ITest{

    /* (non-Javadoc)
    * <p>Title: test</p> 
    * <p>Description: </p>  
    * @see ITest#test()
    */
    @Override
    public void testReflect() {

         System.out.println("I am ITestImpl1 !");
    }
}

class ITestImpl2 implements ITest{

    /* (non-Javadoc)
    * <p>Title: testReflect</p> 
    * <p>Description: </p>  
    * @see ITest#testReflect()
    */
    @Override
    public void testReflect() {

        System.out.println("I am ITestImpl2 !");
    }
    
}


利用反射机制进行解耦的原理:就是利用反射机制"动态"的创建对象:向createITest()方法传入Hero类的包名.类名 通过加载指定的类,然后再实例化对象.