Java反射机制总结

2021/4/25 12:27:15

本文主要是介绍Java反射机制总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

(来自于B站韩老师Java反射专题整理相关笔记,链接:https://www.bilibili.com/video/BV1g84y1F7df)
ps:好像从博客园不能直接跳转,可以复制到浏览器打开

1. 反射机制

1.1 引出:

需求:根据配置文件(xx.properties)创建对象并调用方法

这种需求通过外部文件配置,在不修改源码的情况下,控制程序,符合设计模式的opc原则(开闭原则:不修改源码的情况下,扩展功能)

传统方法难以解决,引出反射机制

1.2 反射机制解决

// 1.加载类,返回Class类型的对象
Class clazz = Class.forName("全类名");
// 2.通过class获得加载类的对象实例
Object o = clazz.newInstance();
// 3.通过class获得加载类的方法对象
// 在反射中,可以将方法视为对象
Method method = clazz.getMethod("方法名");
// 4.通过方法对象来实现方法调用 方法.invoke(对象)
method.invoke(o);

1.3 概念

反射机制就是程序在运行期间借助Reflection API取得任何类的内部信息(成员变量,构造器,成员方法等),并且能够操作对象的属性和方法

类加载完以后,在堆中产生了一个Class类型的对象(一个类只有一个Class对象),该对象包含类的完整结构信息,通过这个对象得到类的结构,这个对象就像一面镜子,透过镜子可以看到类的结构,所以形象的称之为反射

1.4 原理

Java程序执行有三个阶段:

  1. 编译:javac将.java文件编译成字节码文件
  2. 加载:通过类加载器生成Class对象(体现反射)
  3. 运行:创建的对象(堆中)知道自己属于哪个Class对象

1.5 优缺点

优点:动态创建和使用对象,使用灵活

缺点:解释执行,对执行速度有影响

2. Class类

  1. 继承Object类
  2. Class类对象不是new的,而是系统创建的(ClassLoader.loadClass()),可以debug看到
  3. 对于某个类的Class对象,在内存(堆)中只会存在一份,因为类只会加载一次(可以创建两个比较HashCode,值一样)
  4. 每个类的实例知道自己属于哪个Class对象
  5. 通过Class对象可以得到类的完整结构
  6. Class对象存放在堆中
  7. 类的元数据(方法代码,变量名,方法名,访问权限等),即类的字节码二进制数据,存放在方法区

2.2 获取Class类对象

  1. 通过Class.forName()获取:已知类的全类名,且该类在类路径下,多用于配置文件,编译阶段

  2. 类名.class:多用于参数传递 String.class,加载阶段

  3. 对象.getClass():有对象实例,运行阶段

  4. 通过类加载器获取:

    ClassLoader classloader = 对象.getClass().getClassLoader();
    Class cls = classloader.loadClass("全类名");
    
  5. 基本数据类型.class:输出基本类型 int

  6. 包装类.TYPE:输出基本类型

3. 类加载

4. 反射获取类的结构信息

5. 反射相关类

java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造方法

clazz.getField("")方法不能得到私有属性

Class.getConstructor(形参类的class对象)

6. 反射调用性能优化

测试反射调用性能和优化方案:

对同样的类调用90000000次,采用传统方法和反射调用相差数百倍

优化:关闭访问检查

Method、Field、Constructor对象都有setAccessible()方法,可以开启关闭访问安全检查,参数值为true表示反射的对象在使用时取消访问检查,提高性能(优化一点点)

7. Class类常用方法

Class cls = Class.forName("")
System.out.println(cls);//com.xxx.xx 显示cls对象
System.out.println(cls.getClass());//java.lang.Class 运行类型
System.out.println(cls.getPackage().getName());//获取包名
cls.getName();//获取全类名
cls.newInstance();//创建对象实例
Field field = cls.getField("");//获取属性
field.set();//给属性赋值
Field[] fields = cls.getFields();//获取所有属性


这篇关于Java反射机制总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程