Abel's tech blogAbel's tech blog
  • 基础知识
  • 面向对象
  • IO流
  • String
  • 异常处理机制
  • 多线程
  • 反射机制
  • JVM相关知识
  • 数据库基础
  • 数据库进阶
  • 复杂SQL语句
  • Redis
  • Spring-IOC
  • Spring-AOP
  • Spring-Test
  • SpringBoot
  • SpringMVC
  • MyBatis
  • 基于MyBatis的分页查询
  • SpringSecurity
  • 微服务概念
  • Nacos
  • Dubbo
  • Seata
  • Sentinel
  • SpringGateway网关
  • ELK
  • Quartz
  • 消息队列
  • 数据结构
  • 算法
  • TCP/IP
  • 交换机
  • 路由器
  • Docker
  • Kubernetes
  • Linux
  • 各类工具

    • 菜鸟工具
    • 菜鸟教程
    • IDEA下载
    • 数据结构和算法可视化网站
    • jwt解析
    • maven仓库
  • 开发文档

    • Java 8 API 文档
    • Java 17 API 文档
    • MyBatis 3 中文
    • MyBatis-spring 中文
    • Spring Framework 5 API DOC
    • Spring Framework 6 API DOC
    • SpringBoot 2.7.6 API DOC
    • SpringBoot 3 API DOC
    • Hypertext Transfer Protocol -- HTTP/1.0
  • 配置文件下载

    • 阿里云Maven仓库配置
    • Nginx反向代理配置模板
    • JavaScript组件库
  • JDK 8 Windows x86 64-bit
  • JDK 17 Windows x86 64-bit
  • Maven
  • IntelliJ IDEA 各版本
  • Git
  • 基础知识
  • 面向对象
  • IO流
  • String
  • 异常处理机制
  • 多线程
  • 反射机制
  • JVM相关知识
  • 数据库基础
  • 数据库进阶
  • 复杂SQL语句
  • Redis
  • Spring-IOC
  • Spring-AOP
  • Spring-Test
  • SpringBoot
  • SpringMVC
  • MyBatis
  • 基于MyBatis的分页查询
  • SpringSecurity
  • 微服务概念
  • Nacos
  • Dubbo
  • Seata
  • Sentinel
  • SpringGateway网关
  • ELK
  • Quartz
  • 消息队列
  • 数据结构
  • 算法
  • TCP/IP
  • 交换机
  • 路由器
  • Docker
  • Kubernetes
  • Linux
  • 各类工具

    • 菜鸟工具
    • 菜鸟教程
    • IDEA下载
    • 数据结构和算法可视化网站
    • jwt解析
    • maven仓库
  • 开发文档

    • Java 8 API 文档
    • Java 17 API 文档
    • MyBatis 3 中文
    • MyBatis-spring 中文
    • Spring Framework 5 API DOC
    • Spring Framework 6 API DOC
    • SpringBoot 2.7.6 API DOC
    • SpringBoot 3 API DOC
    • Hypertext Transfer Protocol -- HTTP/1.0
  • 配置文件下载

    • 阿里云Maven仓库配置
    • Nginx反向代理配置模板
    • JavaScript组件库
  • JDK 8 Windows x86 64-bit
  • JDK 17 Windows x86 64-bit
  • Maven
  • IntelliJ IDEA 各版本
  • Git

反射机制

反射是java中的动态机制,它允许我们在程序运行期间再确定类的实例化,方法的调用,属性的调用等,而不是传统意义上的在编码期间确定。因此,反射可以大大的提高代码的灵活度,但是随之而来的是更多的系统开销和较慢的运行速度,因此不能过度的依赖反射。

class类

Class的每一个实例用于表示JVM加载的一个类,所以我们也称Class的实例 为类的类对象。 当JVM加载一个类时会同时实例化一个Class的实例与之对应,这个Class实例 中会保存该类的一切信息(类名,有哪些方法,构造器,属性,注解等等) 我们在程序运行期间通过某个类的类对象来操作这个类。因此使用反射操作某个 类的第一件事就是获取该类的类对象

获取一个类的类对象有三种方式:

  • 类名.class 例如: Class cls = String.class; Class cls = int.class (基本类型只能通过这种方式获取类对象)
  • Class.forName(String className) 通过Class的静态方法forName,传入对应类的完全限定名(包名.类名)的 形式获取类对象 Class cls = Class.forName("java.lang.String");
  • 通过类加载器ClassLoader加载类对象

使用反射机制进行对象的实例化

  • Class提供的方法

    • Object newInstance():该方法可以使用其表示的类的无参构造器进行对象实例化
  • 使用有参构造器实例化对象

    • 加载类对象
    • 获取指定的构造器:Person(String name,int age)
  • 使用反射机制调用方法

    • 调用无参数方法
      • 通过类对象获取要调用的方法
      • 通过方法对象执行该方法
    • 调用有参方法
    public class ReflectDemo5 {
      public static void main(String[] args) throws Exception {
          Class cls = Class.forName("reflect.Person");
          Object o = cls.newInstance();
    
          //say(String info)
          Method m = cls.getMethod("say",String.class);
          m.invoke(o,"hello~~");//p.say("hello~~")
    
          //say(String info,int sum)
          Method m2 = cls.getMethod("say",String.class,int.class);
          m2.invoke(o,"嘿嘿",5);
      }
    }
    
    • 访问私有方法
    public class ReflectDemo6 {
      public static void main(String[] args) throws Exception {
          Person p = new Person();
    //        p.hehe();//编译不通过!
    
          Class cls = Class.forName("reflect.Person");
          Object o = cls.newInstance();
    
          //获取私有方法:private void hehe()
    //        Method m = cls.getMethod("hehe");
          //获取私有方法不能用getMethod,(这用来获取公开方法)
          Method m = cls.getDeclaredMethod("hehe");
          m.setAccessible(true);//强制访问
          m.invoke(o);//o.hehe()
      }
    }