Mushroom Notes Mushroom Notes
🍄首页
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
    • 网络编程
    • 设计模式
  • JavaEE

    • Servlet
    • JDBC
    • 会话技术
    • 过滤器监听器
    • 三层架构
  • JDK

    • 总览
  • JVM

    • 总览
  • 常用mate
  • CSS
  • JavaScript
  • rds 数据库

    • MySQL
    • MySQL 进阶
    • MySQL 库表规范
  • nosql 数据库

    • Redis
    • Redis 进阶
    • Redis 底层
    • MongoDB
  • Spring生态

    • Spring
    • Spring MVC
    • Spring boot
    • Spring Validation
  • Spring Cloud生态

    • Spring Cloud
    • 服务治理
    • 远程调用
    • 网关路由
    • 服务保护
    • 分布式事务
    • 消息中间件
  • 数据库

    • Mybatis
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

    • Netty
📚技术
  • 方案专题
  • 算法专题
  • BUG专题
  • 安装专题
  • 网安专题
  • 面试专题
  • 常用网站
  • 后端常用
  • 前端常用
  • 分类
  • 标签
  • 归档

kinoko

一位兴趣使然的热心码农
🍄首页
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
    • 网络编程
    • 设计模式
  • JavaEE

    • Servlet
    • JDBC
    • 会话技术
    • 过滤器监听器
    • 三层架构
  • JDK

    • 总览
  • JVM

    • 总览
  • 常用mate
  • CSS
  • JavaScript
  • rds 数据库

    • MySQL
    • MySQL 进阶
    • MySQL 库表规范
  • nosql 数据库

    • Redis
    • Redis 进阶
    • Redis 底层
    • MongoDB
  • Spring生态

    • Spring
    • Spring MVC
    • Spring boot
    • Spring Validation
  • Spring Cloud生态

    • Spring Cloud
    • 服务治理
    • 远程调用
    • 网关路由
    • 服务保护
    • 分布式事务
    • 消息中间件
  • 数据库

    • Mybatis
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

    • Netty
📚技术
  • 方案专题
  • 算法专题
  • BUG专题
  • 安装专题
  • 网安专题
  • 面试专题
  • 常用网站
  • 后端常用
  • 前端常用
  • 分类
  • 标签
  • 归档
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
      • 动态代理
        • Proxy类
    • 网络编程
    • 设计模式
  • JavaEE

  • JDK版本特性

  • JVM

  • Java
  • JavaSE
kinoko
2023-12-17
目录

反射


概述

在程序的运行过程中, 通过Class对象得到类中的信息(构造方法, 成员方法, 成员变量), 并操作他们 这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。非常规的手段操作对象。

Class类

java中存在一个类叫Class类,Class类创建的对象我们称为Class对象/类对象

Class对象会保存类中的信息(构造方法, 成员方法, 成员变量等) 有了Class对象就能得到类中的所有信息。可以说得到Class对象反射就完成了一半。

反射的应用场景

  • ①IDEA的智能提示
  • ②框架Spring/SpringMVC/Mybatis

利用反射调用它类中的属性和方法时,无视修饰符使用反射创建对象,代码更复杂功能更强大灵活,会破坏封装

三种获取Class对象的方式

  1. 类名.class
  2. 对象.getClass()
  3. Class.forName("类全名");

常用方法

方法 说明
String getSimpleName(); 获得类名字符串:类名
String getName(); 获得类全名:包名.类名
T newInstance 通过Class对象创建对象
操作构造器对象
Constructor<?>[] getConstructors() 返回所有构造器对象的数组(只能拿public的)
Constructor<T> getConstructor(Class<?>... parameterTypes) 返回单个构造器对象(只能拿public的)
Constructor<?>[] getDeclaredConstructors() 返回所有构造器对象的数组,存在就能拿到
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回单个构造器对象,存在就能拿到
构造器对象方法
T newInstance(Object... initargs) 根据指定的构造器创建对象
public void setAccessible(boolean flag) 设置为true,表示取消访问检查,进行暴力反射
操作成员方法对象
Method[] getMethods() 返回所有成员方法对象的数组(只能拿public的)
Method getMethod(String name, Class<?>... parameterTypes) 返回单个成员方法对象(只能拿public的)
Method[] getDeclaredMethods() 返回所有成员方法对象的数组,存在就能拿到
Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回单个成员方法对象,存在就能拿到
成员方法对象的方法
Object invoke(Object obj, Object... args) 运行方法

参数一:方法的调用者 参数二:调用方法的传递的参数(如果没有就不写) 返回值:方法的返回值(如果没有就不写) | | 操作成员变量 | | | Field[] getFields() | 返回所有成员变量对象的数组(只能拿public的) | | Field getField(String name) | 返回单个成员变量对象(只能拿public的) | | Field[] getDeclaredFields() | 返回所有成员变量对象的数组,存在就能拿到 | | Field getDeclaredField(String name) | 返回单个成员变量对象,存在就能拿到 | | 成员变量方法 | | | void set(Object obj, Object value): | 赋值 | | Object get(Object obj) | 获取值 |

**注意:**反射中方法参数类型若是泛型,则需要传入Object.class

# 动态代理


代理模式三要素

你 -> 黄牛-> 12306买票

  1. **真实对象: **真正工作的对象12306
  2. 代理对象: 黄牛
  3. 抽象对象: 代理对象和真实对象都要实现的接口 (卖票接口)

什么是动态代理?在程序的运行过程中创建出代理对象 动态代理的好处:可以对功能进行增强或拦截

# Proxy类


介绍: 动态代理类

常用构造

方法 说明
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h) 创建代理对象
参数:
ClassLoader loader: 类加载器, 固定写法 当前类名.class.getClassLoader()
Class<?>[] interfaces: 多个接口, 代理对象会实现这些接口
InvocationHandler h: 执行处理器接口, 放入匿名内部类

示例

需求: 统计list方法的执行时间,拦截remove方法

public class TestCode {

    public static void main(String[] args) {
        // 创建真实对象
        ArrayList<Integer> list = new ArrayList<>();

        // 创建动态代理对象
        Object proxy = Proxy.newProxyInstance(
                // 固定写法
                TestCode.class.getClassLoader(),
                // 代理对象需要实现的接口
                new Class[]{List.class},
                // 代理对象调用任何方法都会执行invoke
            	// invoke相当于重写了接口的所有方法,可以做统一处理
                new InvocationHandler() {
                    @Override              //代理对象        调用方法           参数
                    public Object invoke(Object proxy, Method method, Object[] args) 
                        throws Throwable {
                        // 对方法进行拦截
                        if (method.getName().equals("remove")) {
                            System.out.println("已拦截remove方法");
                            return null;
                        }
                        // 对方法进行增强
                        long start = System.currentTimeMillis();
                        // 相当于list.add(1)   方法名.调用(调用者,参数)
                        Object res = method.invoke(list, args);
                        long end = System.currentTimeMillis();
                        System.out.println(
                            method.getName() + "耗时" + (end - start) + "ms");
                        return res;
                    }
                });

        List plist = (List) proxy;
        plist.add(1);
        plist.add(2);
        System.out.println(plist);
        plist.remove(1);
        System.out.println(plist);

    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#java#反射
上次更新: 2023/12/29 11:32:56
JUC
网络编程

← JUC 网络编程→

最近更新
01
JVM 底层
09-13
02
JVM 理论
09-13
03
JVM 应用
09-13
更多文章>
Theme by Vdoing | Copyright © 2022-2024 kinoko | MIT License | 粤ICP备2024165634号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式