反射

获取Class实例的四种方式

 @Test
    //创建反射的四种方式:
    public void test1() throws ClassNotFoundException {
        Class clazz1=Person.class;
        Person p=new Person();
        Class clazz2=p.getClass();
        Class clazz3=Class.forName("Reflection.Person");
//        System.out.println(clazz1==clazz2);      //true
//        System.out.println(clazz2==clazz3);       //true
        //方式四(了解):ClassLoader
        ClassLoader classLoader=ReflectionTest.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("Reflection.Person");
    }

类加载器ClassLoader的理解

image.png
image.png

体会反射的动态性

 @Test
    public void dongtaixing() throws IllegalAccessException, InstantiationException, ClassNotFoundException {

        for (int j = 0; j <10 ; j++) {
            int i = new Random().nextInt(3);
            String classPath="";
           switch (i){
               case 0:;classPath="java.lang.Object";break;
               case 1:classPath="java.util.Date";break;
               case 2:classPath="Reflection.ReflectionTest";break;
           }
            System.out.println(getInstance(classPath));

        }


    }
    public Object getInstance(String s) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class clazz = Class.forName(s);
        return clazz.newInstance();
    }

获取运行时类的(属性、方法、构造器等)及其内部结构

属性

image.png
image.png
权限修饰符可以用toString方法将代码转为方法

方法

image.png

构造器、父类(包含带泛型)、接口等

image.png
image.png

调用获取运行时类的(属性、方法、构造器等)

调用运行时类的属性

   @Test
    //调用运行时类的属性
    public void test3() throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        Class<Person> clazz = Person.class;
        Person p = clazz.newInstance();
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);//这一步很重要
        name.set(p, "反射");
        System.out.println(name.get(p));//等价于下方代码
       // System.out.println(p.getName());
    }

调用运行时类方法(包含静态方法与非静态方法)

 @Test
    //调用运行时类的方法(包含静态方法与非静态方法)
    public void test4() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<Person> clazz = Person.class;
        Person p = clazz.newInstance();
        Method show = clazz.getDeclaredMethod("show", String.class);
        show.setAccessible(true);
        Object s = show.invoke(p, "学习使我快乐");
        System.out.println(s);
        System.out.println("****************下面时调用静态方法****************");
        Method staticShow = clazz.getDeclaredMethod("staticShow");
        staticShow.setAccessible(true);
        Object invoke = staticShow.invoke(null);//静态方法这里可以填null
        System.out.println(invoke);//由于此处并没有返回值,所以是null
    }

运行截图:
image.png

调用有参构造器

之前的例子中用clazz.newInstance()返回一个对象均默认调用空参构造器。下面的代码展示的是如何通过反射调用有参构造器

   //调用构造器,不用先建对象,通过构造器来建对象
    @Test
    public void test5() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class clazz = Class.forName("Reflection.Person");
        Constructor con = clazz.getDeclaredConstructor(String.class, int.class);//某一类的构造器名称都已知,不用写方法名
        con.setAccessible(true);
        Object p = con.newInstance("向往", 22);
        System.out.println(p);
    }

动态代理

首先先熟悉静态代理设计模式

静态代理

public interface ClothFactory {
    public void make();
}

class NikeClothFactory implements ClothFactory {

    @Override
    public void make() {
        System.out.println("Nike生产了一件衣服");
    }
}

//代理类,静态代理里面用到,动态代理不需要
class ProxyClothFactory implements ClothFactory {
    private ClothFactory cf;//可以这样写

    public ProxyClothFactory(ClothFactory cf) {
        this.cf = cf;
    }

    @Override
    public void make() {
        System.out.println("代理类的前序工作");
        cf.make();//既然要在此处调用被代理类的方法,就先要有被代理类的对象
        System.out.println("代理类的后续工作");

    }
}
  //静态代理
    @Test
    public void test6(){
        NikeClothFactory ncf = new NikeClothFactory();
        ProxyClothFactory pcf = new ProxyClothFactory(ncf); //以后可以全使用代理对象来调用被代理对象了
        pcf.make();

    }

运行截图:
image.png

动态代理

所用的接口和类和上例一样

    //动态代理
    @Test
    public void test7(){
        NikeClothFactory ncf = new NikeClothFactory();
        ClothFactory proxyInstance = (ClothFactory)ProxyFactory.getProxyInstance(ncf);
        proxyInstance.make();

    }
}
class ProxyFactory{
    public static Object getProxyInstance(Object obj){
        MyInvocationHandler handler = new MyInvocationHandler();
        handler.bind(obj);
        return  Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),handler);
    }
        }

class MyInvocationHandler implements InvocationHandler {
    Object obj;
    public void bind(Object obj){
        this.obj=obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object returnVal = method.invoke(obj, args);
        return returnVal;
    }
}

运行截图:
image.png

Q.E.D.