动态代理与反射

 动态代理

接口:

public interface Star {
    public String sing(String name);
    public void dance();
}

 实现类:

public class BigStar implements Star{
    private String name;

    public BigStar() {
    }

    public BigStar(String name) {
        this.name = name;
    }

    @Override
    public String sing(String name) {
        System.out.println(this.name+"正在唱"+name);
        return "谢谢";
    }

    @Override
    public void dance() {
        System.out.println(this.name+"正在跳舞");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "daili.BigStar{" +
                "name='" + name + '\'' +
                '}';
    }
}

 代理类:

public class ProxyUtil {
    public static Star createProxy(BigStar bigStar) {
        //代理类的类加载器、Class数组、InvocationHandler对象(实现invoke方法)
        Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{Star.class}, new InvocationHandler() {
                    //InvocationHandler接口必须实现invoke方法,参数为目标类对象、目标类方法、目标类方法参数数组
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if ("sing".equals(method.getName())) {
                            System.out.println("准备话筒,收钱");
                        } else if ("dance".equals(method.getName())) {
                            System.out.println("准备场地,收钱");
                        }
                        method.invoke(bigStar, args);
                        return "谢谢";
                    }
                }
        );
        return star;
    };
}

 测试类:

public class Test {
    public static void main(String[] args) {
        BigStar bigStar = new BigStar("鸡哥");//创建目标对象
        Star proxy = ProxyUtil.createProxy(bigStar);//创建代理对象

        String result = proxy.sing("只因你太美");
        System.out.println(result);

        proxy.dance();
    }
}

反射

获取类的class对象,描述字节码文件的,用io流不能区分方法,变量和构造器;

结合配置文件动态创建对象。

获取类的class方法的三种方式

源代码阶段

Class clazz = Class.forName("fanshe.Student");

 加载阶段

Class clazz2 = Student.class;

 运行阶段

Class clazz3 = new Student().getClass();

反射获取类的构造方法

实体类

public class Student {
    private String name;
    private int age;
    public Character gender;

    public Student(String name) {
        this.name = name;
    }

    Student(int age) {
        this.age = age;
    }

    private Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 测试类

public static void main(String[] args) throws Exception {
        //获取class字节码文件对象
        Class clazz = Class.forName("fanshe.Student");
        Constructor constructor1 = clazz.getConstructor(String.class);
        int modifiers1 = constructor1.getModifiers();
        System.out.println("public:1  :0 protected:4 private:2");
        System.out.println("获取权限修饰符:"+modifiers1);
        System.out.println(constructor1);
        System.out.println("===============================================");

        Constructor declaredConstructor1 = clazz.getDeclaredConstructor(int.class);
        Constructor declaredConstructor2 = clazz.getDeclaredConstructor(String.class, int.class);
        System.out.println(declaredConstructor1+"\n"+declaredConstructor2);
        System.out.println("获取构造方法参数:" +
                "\n"+declaredConstructor2.getParameters()[0]+
                "\n"+declaredConstructor2.getParameters()[1]);
        declaredConstructor2.setAccessible(true);
        System.out.println(declaredConstructor2.newInstance("张三",23));
        System.out.println("===============================================");

        //获取所有public修饰的构造方法
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("===============================================");

        //获取所有构造方法
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
    }

反射获取成员变量

 测试类

public static void main(String[] args) throws Exception {
        //获取class字节码文件对象
        Class clazz = Class.forName("fanshe.Student");
        System.out.println(clazz);
        //获取所有成员变量(包括非public修饰的)
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("===============================");
        Field gender = clazz.getDeclaredField("gender");
        System.out.println(gender+",修改符:"+gender.getModifiers()+
                "\n"+"名称:"+gender.getName()+
                "\n"+"类型:"+gender.getType());
        //获取对象的私有成员变量的值
        Field name = clazz.getDeclaredField("name");
        Student student = new Student("张三");
        name.setAccessible(true);
        Object o = name.get(student);
        System.out.println(o);
    }

反射获取成员方法及方法参数

 测试类

public static void main(String[] args) throws Exception {
        //获取class字节码文件对象
        Class clazz = Class.forName("fanshe.Student");
        //获取本类中所有public方法
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("====================================");
        //不能获取父类,但是可以获取本类中非public的方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("====================================");
        Method setAge = clazz.getMethod("setAge", int.class);//有重载
        System.out.println(setAge+",修饰符:"+setAge.getModifiers());
        System.out.println("方法的参数:");
        Class[] parameterTypes = setAge.getParameterTypes();
        for (Class parameterType : parameterTypes) {
            System.out.println(parameterType);
        }
        System.out.println("====================================");
        System.out.println("方法抛出的异常:");
        Class[] exceptionTypes = setAge.getExceptionTypes();
        for (Class exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }
        System.out.println("=======================");
        Student student = new Student("李四");
        Method setName = clazz.getMethod("setName", String.class);
        setName.invoke(student,"王五");
        System.out.println(student);
    }

反射结合IO流写出类信息

 测试类

Student student = new Student("李四");
student.setAge(23);
student.gender='男';
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("C:\\Users\\25130\\Desktop\\t3.txt"));
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
   declaredField.setAccessible(true);             
   bufferedOutputStream.write((declaredField.getName()+":"+
   declaredField.get(student)+"\n").getBytes());
}
bufferedOutputStream.close();

反射读配置文件,动态创建对象和运行方法

public static void main(String[] args) {
        try (FileInputStream fileInputStream = new FileInputStream("prop.properties");) {
            Properties properties = new Properties();//HashTable的子类
            properties.load(fileInputStream);//添加流
            System.out.println(properties);//{classname=fanshe.Student, method=setName}
            String classname = (String) properties.get("classname");
            String method = (String) properties.get("method");
            System.out.println(classname + "====" + method);
            Class clazz = Class.forName(classname);//fanshe.Student
            Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
            System.out.println(declaredConstructor);
            Student student = (Student) declaredConstructor.newInstance("王五");
            System.out.println(student);//Student{name='王五', age=0}
            Method declaredMethod = clazz.getDeclaredMethod(method, String.class);
            declaredMethod.invoke(student, "张三");
            System.out.println(student);//Student{name='张三', age=0}
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值