通过反射调用类的完整结构;静态代理类 && 动态代理类的使用。

 

二、创建类对象并获取类的完整结构:

 

package com.atguigu.fanshe;



import org.junit.Test;



public class TestConstructor {

    @Test

    public void test1() throws Exception {

        String className="com.atguigu.fanshe.Person";

        Class clazz1=Class.forName(className);//加载一下

        //创建对应运行时类的对象

        //(newInstance调用的就是类的空参构造器)

        //要想能够创建成功:①、要求对应的运行时类要有空参的构造器。②、构造器的权限修饰符的权限要足够

        Object obj=clazz1.newInstance();//newInstance默认的返回值类型位Object类型

        Person p=(Person)obj;

        System.out.println(p);

       

    }

}

 

 

1、Field类(获取运行时类的属性):

       (1)getFields():只能获取到运行时类及其父类中声明的public类型的属性的数组形式。

        Class clazz1=Person.class;

        Field[] field1=clazz1.getFields();

        for(int i=0;i<field1.length;i++) {

            System.out.println(field1[i]);

        }

        System.out.println("*****");

    (2)getDeclaredFields():获取运行时类本身声明的所有的属性。

        Field[] field2=clazz1.getDeclaredFields();

        for(Field f:field2) {

            System.out.println(f.getName());

        }

 

    (3)、权限修饰符 变量类型 变量名获取属性各个部分的内容

    @Test

    public void testField2() {

        Class clazz=Person.class;

        Field[] field1=clazz.getDeclaredFields();

        for(Field f:field1) {

            //1、获取每个属性的权限修饰符

            int i=f.getModifiers();

            String str1=Modifier.toString(i);

            System.out.print(str1+" ");

            //2、获取属性的变量类型

            Class type=f.getType();

            System.out.print(type.getName()+" ");

            //3、获取属性名

            System.out.print(f.getName()+" ");

           

            System.out.println();

        }

    }

 

2、Method类(获取运行时类的方法):

 

package com.atguigu.fanshe;

 

import java.lang.annotation.Annotation;

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

 

import org.junit.Test;

 

public class TestMethod {

    @Test

    public void test1() {

        Class clazz=Person.class;

        //1getMethods():获取运行时类及其父类中所有的声明为public的方法

        Method[] m1=clazz.getMethods();

        for(Method m:m1) {

            System.out.println(m);

        }

       

        //2getDeclaredMethods():获取运行时类本身声明的所有方法

        Method[] m2=clazz.getDeclaredMethods();

        for(Method m:m2) {

            System.out.println(m);

        }

    }

   

    //注解 权限修饰符 返回值类型 方法名 形参列表 异常

    @Test

    public void test2() {

        Class clazz=Person.class;

       

        Method[] m2=clazz.getDeclaredMethods();

        for(Method m:m2) {

            //1、注解:

            Annotation[] ann=m.getAnnotations();

            for(Annotation a:ann) {

                System.out.println(a);

            }

            //2、权限修饰符

            String str=Modifier.toString(m.getModifiers());

            System.out.println(str+" ");

            //3、返回值类型

            Class returnType=m.getReturnType();

            System.out.println(returnType.getName()+" ");

            //4、方法名

            System.out.println(m.getName());

           

            //5、形参列表

           

            //6、异常类型

           

        }

    }

}

3、Constructor类(获取运行时类的方法):

 

4、其他类:

package com.atguigu.fanshe;



import java.lang.annotation.Annotation;

import java.lang.reflect.ParameterizedType;

import java.lang.reflect.Type;



import org.junit.Test;



public class TestOther {

    //6、获取注解

    @Test

    public void test6() {

        Class clazz=Person.class;

        Annotation[] anns=clazz.getAnnotations();

        for(Annotation a:anns) {

            System.out.println(a);

        }

    }

   

   

   

    //5、获取所在的包

    @Test

    public void test5() {

        Class clazz=Person.class;

        Package pack=clazz.getPackage();

        System.out.println(pack);

    }

   

   

    //4、获取实现的接口

    @Test

    public void test4() {

        Class clazz=Person.class;

        Class[] interfaces=clazz.getInterfaces();

        for(Class i:interfaces) {

            System.out.println(i);

        }

    }

   

   

    //*非常重要**3、获取父类的泛型

    @Test

    public void test3() {

        Class clazz=Person.class;

        Type type1=clazz.getGenericSuperclass();

       

        ParameterizedType param=(ParameterizedType)type1;

        Type[] ars=param.getActualTypeArguments();

        System.out.println(((Class)ars[0]).getName());

    }

   

   

   

   

    //2、获取带泛型的父类

    @Test

    public void test2() {

        Class clazz=Person.class;

        Type type1=clazz.getGenericSuperclass();

        System.out.println(type1);

    }

   

   

    //1、获取运行时的父类

    @Test

    public void test1(){

        Class clazz=Person.class;

        Class superClass=clazz.getSuperclass();

        System.out.println(superClass);

    }

}

 

 

 

 

 

 

三、通过反射调用类中的指定方法、指定属性:

 

 

1、调用类中指定的属性:   

@Test

    public void test3() throws Exception {

        Class clazz=Person.class;

        //1、获取指定的属性

        //getField(String name):获取运行时类中声明为public的指定属性名为name的属性

        Field name=clazz.getField("name");

        //2、创建运行时类的对象

        Person p=(Person)clazz.newInstance();

        System.out.println(p);

        //3、将运行时类的指定属性赋值

        name.set(p,"Jerry");

        System.out.println(p);

       

        System.out.println();

        //getDeclaredField(String name):获取运行时类中指定的名为name的属性

        Field age=clazz.getDeclaredField("age");

        //由于属性权限修饰符的限制,为了保证可以给属性赋值,需要在操作前使得此属性可被操作。

//      age.setAccessible(true);   //如果属性是私有的需要加此语句

        age.set(p, 23);

        System.out.println(p);

       

    }

2、调用类中指定的方法:

       getMethod(String methodName,Class … params):获取运行时类中声明为public的指定的方法。

       invoke():调用指定的方法。

 

3、调用类中指定的构造器:

 

 

四、反射的应用之动态代理:

1、静态代理类的编写规则:

package dongtaidaili;

//静态代理



//1、接口

interface ClothFactory{

    void productCloth();

}

//2、被代理类

class NickClothFactory implements ClothFactory{



    @Override

    public void productCloth() {

        // TODO Auto-generated method stub

        System.out.println("Nick工厂生产一批衣服");

    }

}

//3、代理类

class ProxyFactory implements ClothFactory{



   

    ClothFactory cf;

    //创建代理类的对象时,实际传入一个被代理类的对象

    public ProxyFactory(ClothFactory cf) {

        this.cf=cf;

    }

    @Override

    public void productCloth() {

        // TODO Auto-generated method stub

        System.out.println("代理类开始执行,收代理费¥1000");

        cf.productCloth();

    }  

   

}

public class TestClothProduce {

    public static void main(String[] args) {

        NickClothFactory nick=new NickClothFactory();//创建被代理类的对象

        ProxyFactory proxy=new ProxyFactory(nick);//创建代理类的对象

        proxy.productCloth();

    }

}



//一个接口对应一个被代理类和一个代理类。杂。

 

2、静态代理类的编写规则:

package dongtaidaili;



import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;



//动态代理类的使用

interface Subject {

    void action();

}



//被代理类

class RealSubject implements Subject {

    public void action() {

        System.out.println("我是代理类,记得要执行我i偶!");

    }

}



//凡是与动态代理相关的,都要实现InvocationHandler接口。

class MyInvocationHandler implements InvocationHandler {

    Object obj;// 实现了接口的被代理类的对象的声明,相当于RealSubject的对象。



    // ①、给被代理类的对象实例化;②、返回一个代理类的对象

    public Object blind(Object obj) {

        this.obj = obj;

        // Proxy.newProxyInstance(arg0, arg1, arg2)//;;return语句真正的相当于返回了一个代理类的对象

        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);

    }



    //当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下的invoke方法的调用

    @Override // 调用invoke()方法时,实际调用的是action()方法。

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object returnVal=method.invoke(obj, args);

        return returnVal;

    }



}



public class TestProxy {

    public static void main(String[] args) {

        //1、被代理类的对象

        RealSubject real=new RealSubject();

        //2、创建一个实现了InvocationHandler接口的类的对象

        MyInvocationHandler handler=new MyInvocationHandler();

        //3、调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象

        Object obj=handler.blind(real);

        Subject sub=(Subject)obj;//此时sub就是代理类的对象

        sub.action();//转到对InvocationHandler接口的实现类的invoke()方法的调用

       

        //再举一例

        NickClothFactory nick=new NickClothFactory();

        ClothFactory proxyCloth=(ClothFactory)handler.blind(nick);//proxyCloth即为代理类的对象。

        proxyCloth.productCloth();

    }

}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值