反射理解

简介: 个人对反射的学习理解与代码

反射理解

集合中的泛型只在java文件中存在,当编译成class文件之后,就没有泛型了。

首先获取类的class对象

获取对象的方式有三种

Class这个类里面的静态方法forName(“全类名”)

通过class属性获取 通过对象获取字节码文件对象

然后通过class对象可以去获取相关的构造器,成员变量.成员方法

Constructor是构造器

Field是成员变量

Method是成员方法

共性 都通过get set 去获取去修改

Declared表示获取全部权限的内容,如果不加默认是public

加上s表示全部,返回一个集合,遍历集合可以得到所有信息.

临时开启权限

如果当前获取到的是私有的,必须要临时修改访问权限,否则无法使用

不管是属性还是方法 都得这么操作

方法为setAccessible(true);

在我们不确认权限修饰符,或者说就算确定了也可以开启权限,因为他是没有危害的,加了一定没错

获取到成员方法然后用获取到的成员方法对象去调用invoke方法去传入对象与方法形参去调用方法

获取方法的时候 如果方法名相同,要通过形参列表去区分具体想要获得的是哪一个方法.

形参的传入也需要是类型的class对象,比如String.class

场景1 :动态获取配置文件中的信息然后拿来使代码更加灵活

第一步 要先新建一个文件类型为properties的文件

2: Properties prop = new Properties(); 创建Properties对象

3: 使用io流读取配置文件 字节流字符流都可以去读取,因为load对象参数可以是字节也可以是字符读取流

然后通过prop.load(io流对象); 读完关流

4:然后就是通过prop去get配置文件里面的信息

比如prop.get("classname") 就可以得到类名 通过类名就可以得到class对象

然后就可以做反射能做的事情了

场景2:利用发射保存对象中的信息

首先还是获得类的class对象 然后进行一系列的获取我们想要的消息

最后通过io流写入流写入就可以了

场景3:动态代理

动态代理好处就是可以实现无侵入式的修改代码,加入我们想要增强的功能

第一步 创建一个类 类的作用用来创建一个代理 ProxyUtil

第二步 在类中定义一个静态方法 作用用来返回一个代理

第三步 方法内调用Proxy.newProxyInstance方法

{参数一 : 类的加载器 即你要在哪个类里面获取这个代理对象 ProxyUtil.class.getClassLoader(),

参数二 : 指定接口代理范围 new Class[]{Star.class},在这里我代理的是star

参数三: 用于代理要去做什么事,即我们的核心 增强功能

参数三为匿名内部类 }

其中也有三个参数

参数一 代理的对象 在这里是star去代理bigstar,所以就是star
参数二 要运行的方法 method就是外部我们调用的时候传进来的一个方法对象 比如我们调用sing传入进来的就是sing对象
参数三调用运行的方法时,传递的实际参数 比如我们调用sing时候,传入进来的参数"鸡你太美", 在这里是一个数组,是按照形参顺序存储进来的数组 在这个方法我们通过数组加索引可以操作我们传递进来的实参

此时匿名内部类的方法作用就是增强功能 完成之后要结束方法

增强功能之后 要去让本来有的功能去实现原有的功能

所以增强功能就是return method.invoke(原本的功能代码对象 在这里是bigstar, 这里是实参 也就是args);

如果是拦截就是直接return null;

最后 createProxy的返回值就是返回一个代理, 将Proxy.newProxyInstance 获取到的对象去强转

return 出去即可,这就是动态代理的思路即实现

package _动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyUtil {
    //    类的作用 创建一个代理
    public static Star createProxy(BigStar bigStar) {

        Star star = (Star) Proxy.newProxyInstance(
//            参数一 类的加载器
                ProxyUtil.class.getClassLoader(),
//            参数二 指定接口代理范围
                new Class[]{Star.class},
//            参数三 用于指定生成的代理要去做什么事情
                new InvocationHandler() {
                    @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("准备场地收钱");
                        }
//                        增强功能之后 要去让本来有的功能去实现原有的功能
                        return method.invoke(bigStar, args);
                    }
                }
        );
        return star;
    }
}

 //可以增强方法,

//也可以拦截方法.拦截方法的代码形式为 如果代理识别到外部调用这个方法我们想要拦截,直接


 if("cleanWC".equals(method.getName())){
                        System.out.println("拦截,不调用大明星的方法");
                        return null;
                    }
相关文章
|
7月前
反射
何为反射?在运行状态时,对于任何一个类,都能够动态获取这个类得所有方法和属性(私有,公有,受保护),都能够调用任意一个方法和属性。
26 0
|
4月前
|
Java 数据库连接 数据库
JVAVEE反射
JVAVEE反射
28 0
|
7月前
|
安全 数据可视化 IDE
反射(二)什么是反射
反射(二)什么是反射
30 0
|
10月前
|
缓存 前端开发 JavaScript
一起来学反射(上)
一起来学反射
76 0
|
10月前
|
设计模式 安全 Java
一起来学反射(下)
一起来学反射
69 0
反射小练习
通过反射创建级联对象
反射之IllegalAccessException、NoSuchFieldException
本文目录 1. IllegalAccessException 2. NoSuchFieldException
360 0
|
Java
反射总结
反射总结
76 0