反射以及动态代理的使用

1.什么是反射?

反射允许对成员变量,成员方法和构建方法的信息进行编程访问。

2.如何获取Class对象

  • Class.forName(“全类名”); 源代码阶段使用,Java文件
  • 类名.class 加载阶段,class文件
  • 对象.getClass(); 运行阶段,对象已经生成。{A a = new A();}
		//第一种方式
		//全类名: 包名 + 类名  
		//最为常用的
        Class<?> aClass = Class.forName("com.dome01.KunKun.java");
        //第二种方式
		//一般更多是当做参数进行传递
        Class<KunKun> aClass1 = KunKun.class;
        //第三种方式
		//当我们已经有了这个类的对象时,才可以是使用。
        KunKun kunKun = new KunKun();
        Class aClass2 = kunKun.getClass();

通过反射能够对成员变量,成员方法和构造方法的信息进行编程访问。

在这里插入图片描述

以构造方法为例,演示反射的用法。

import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;

public class Cline {
    public static void main(String[] args) throws Exception {
        Class aClass = Class.forName("com.dome02.Student");
        //1.获取所有公共构造方法
        Constructor[] cons = aClass.getConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("==================");
        //2.获取所有构造方法
        //Declared  正式宣布的,公开声明的
        Constructor[] allCons = aClass.getDeclaredConstructors();
        for (Constructor allCon : allCons) {
            System.out.println(allCon);
        }
        System.out.println("==================");
        /*
            3.获取单个公共构造方法
            public Constructor<T> getConstructor(Class<?>... parameterTypes)
            需传入对应的参数类型的字节码
         */
        Constructor constructor = aClass.getConstructor(String.class,int.class,String.class);
        System.out.println(constructor);
        //4.获取单个构造方法
        System.out.println("==================");
        Constructor declaredCons = aClass.getDeclaredConstructor(String.class,int.class);
        System.out.println(declaredCons);
        //拿到该构造方法后能够对其编码获取其他信息
        //5.获取该构造方法的修饰符
        System.out.println("获取该构造方法的修饰符");
        int modifiers = declaredCons.getModifiers();
        System.out.println(modifiers);
        //6.获取该构造方法的参数
        System.out.println("获取该构造方法的参数");
        Parameter[] parameters = declaredCons.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        //7.通过该构造方法创建对象
        //设置该私有构造方式访问权限,能够修改和访问原本无法访问的成员
        declaredCons.setAccessible(true);
        Student student = (Student) declaredCons.newInstance("张三",25);
        System.out.println(student.getName());
    }
}

若不设置访问权限,通过该方法创建的对象为私有构造器定义的对象,则会直接抛出异常

Class com.dome02.Cline can not access a member of class com.dome02.Student with modifiers “private”

3.什么是动态代理?

无侵入式的给代码增加额外的功能。动态代理是对对象已有方法的增强,不能给对象新增方法。

4.如何知道那些方法需要代理

定义一个接口,在接口中定义方法,对象实现该接口。

5.如何创建代理对象?

java.lang.reflect.Proxy 类中提供了为对象产生代理对象的方法:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
    /**
    	参数一:指定用那个类加载器,去加载生成的代理类。(即需要代理的对象的类加载器,通过获得对象的字节码来过的类加载器)
    
		参数二:指定接口,指定代理有哪些方法。
	
		参数三:指定生成的代理对象要干什么事情
	*/
new InvocationHandler(){
    public Object invock(Object proxy,Method method,Object[]args)throws Throwable{
        /**
        	参数一:代理的对象,一般不用修改。
        	参数二:要运行的方法。
        	参数三:调用方法时需要传入的参数。
        	*/
        //对方法进行增强处理。
        
        //调用对象方法,返回结果值,即被代理方法的结果值。也可对结果进行处理在返回。
        return method.invoke(Object,args);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值