Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
  • Java语法

    • String
    • 面向对象
    • 反射
      • 为什么用反射
      • 反射作用
      • 反射应用场景
      • 反射优缺点
      • Class类
      • 反射相关操作
      • 通过反射了解集合泛型本质
    • 泛型
    • 序列化
    • 动态代理
    • IO
    • 回调
    • SPI
    • 异常
    • 注解
  • Java容器

  • Java新特性

  • IDEA常用快捷键
  • 正则表达式
  • API
  • 场景题

  • JavaSE
  • Java语法
Nreal
2023-11-21
目录

反射

# 为什么用反射

# 反射作用

动态编译与静态编译:

  • 动态编译:运行时确定类型,绑定对象;最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性;
  • 静态编译:编译时确定类型,绑定对象;

反射可以在程序运行时分析类;

# 反射应用场景

  • JDK动态代理,使用了反射类 Method 来调用指定方法;
  • 注解,如@Value 基于反射分析类,获取到类/属性/方法/方法的参数;

# 反射优缺点

优点:实现动态创建对象和编译,体现出很大的灵活性;

一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。

缺点:对性能有影响;

反射是一种解释操作,告诉JVM希望做什么并让它满足我们的要求,这类操作总是慢于只直接执行相同的操作;

# Class类

所有类的类;

其构造器是私有的,只有JVM可以创建Class对象,不能new,但是可以通过已有的类得到一个Class对象;

Class c1 = Dog.class;//这说明任何一个类都有一个隐含的静态成员变量class,这种方式是通过获取类的静态成员变量class得到的
Class c2 = cat.getClass();//cat是一个对象实例,通过一个类的对象的getClass()方法获得的;
Class c3 = Class.forName("com.Nreal.Animal");
1
2
3

可以通过类类型知道一个类的属性和方法,并且可以调用一个类的属性和方法;

# 反射相关操作

Java 基础与提高干货系列——Java 反射机制 - 掘金 (juejin.cn) (opens new window)

# 通过反射了解集合泛型本质

Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译到了运行期就无效了;

案例:给List<String>添加一个int类型元素;

public class GenericEssence {
    public static void main(String[] args) {
        List list1 = new ArrayList(); 
        List<String> list2 = new ArrayList<String>();

        list2.add("hello");
//      list2.add(20); // 报错!list2有泛型限制,只能添加String,添加int报错
        System.out.println("list2的长度是:" + list2.size()); // 此时list2长度为1

        /*
         * 然后通过反射添加元素方式,在运行期动态加载类,首先得到list1和list2
         * 的类类型相同,然后再通过方法反射绕过编译器来调用add方法,看能否插入int
         * 型的元素
         */
        Class c1 = list1.getClass();
        Class c2 = list2.getClass();
        System.out.println(c1 == c2); // 结果:true,说明类类型完全相同

        // 验证:我们可以通过方法的反射来给list2添加元素,这样可以绕过编译检查
        try {
            Method m = c2.getMethod("add", Object.class); // 通过方法反射得到add方法
            m.invoke(list2, 20); // 给list2添加一个int型的,上面显示在编译器是会报错的
            System.out.println("list2的长度是:" + list2.size()); // 结果:2,说明list2长度增加了,并没有泛型检查
        } catch (Exception e) {
            e.printStackTrace();
        }

        /*
         * 综上可以看出,在编译期的时候,泛型会限制集合内元素类型保持一致
         * 运行期以后,泛型就不再起作用了,即使是不同类型的元素也可以插入集合。
         */
    }
}
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
面向对象
泛型

← 面向对象 泛型→

Theme by Vdoing | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式