Java知识系列 -- 反射
原理
要想理解 Java 反射,首先要弄清类的加载过程。
比如这行代码 Person p = new Person();
。
我们想要创建一个 Person 对象,并用 p 作为对象的引用。
在 Java 虚拟机会先执行类的加载,然后才生成对象(分配内存空间)。在类的加载过程中,类加载器负责把类编译好的 class (字节码)文件加入到内存中,并创建一个 Class 对象,这个对象是类 Class 的实例。
也就是说,上面的一行的代码看似只是创建了一个 Person 对象,但是如果是第一次使用该类,也即类加载器还未把该类的 class 文件加载到内存中时,还会创建一个Class 对象。
在 Java 中,一切都是对象。类是对一类对象的抽象,类是一个概念,而类本身也是一种对象,在 Java 中,它们是 Class 类的对象,当然方法、属性、注解也分别是 Method、Field、Annotation 的对象。
所以,反射干的就是干预程序运行期做的事情。比如创建一个在编译期不能确定的类(子类)。
在编码阶段不知道那个类名,这时候就没有办法硬编码new ClassName(),而必须用到反射才能创建这个对象。
在xml文件或者properties里面写好配置,然后在Java类里面解析xml或properties里面的内容,得到一个字符串。
然后用反射机制,根据这个字符串获得某个类的Class实例,这样就可以动态配置一些东西,不用每一次都要在代码里面去new或者做其他的事情。反射的目的就是为了扩展未知的应用。
使用
获取 Class 对象的三种方法
Class 对象是我们使用反射的关键,而得到这个对象有下面三种方式。
- 调用 Class 类的 forName() 静态方法
- 调用类的隐藏类属性 class。
- 使用对象来获取,调用祖先类 Object 中的方法:
public final native Class<?> getClass()
推荐使用第二种方式来获取 Class 对象,因为在编译期就会检查该类是否存在,更加安全,并且因为没有方法调用,使用的是属性,所以性能也更高。
Class 对象中的方法
可以说我们得到了 Class 对象,就得到了这个类的所有信息了。包括各种获取 构造方法、属性、方法、注解 的方法。
其他常用方法
public String getName() // 返回 Class 对象表示的类型(类、接口、数组或基本类型)的完整路径名字符串
public T newInstance() // 此方法是 Java 语言 instanceof 操作的动态等价方法
public ClassLoader getClassLoader() // 获取该类的类加载器
public Class getSuperclass() // 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class
public boolean isArray() // 如果 Class 对象表示一个数组则返回 true, 否则返回 false
public boolean isInterface() // 判定指定的 Class 对象是否表示一个接口类型
public boolean isPrimitive() // 判定指定的 Class 对象是否表示一个 Java 的基本类型
例子
在我们写代码时,在对象后面敲一个 . ,IDE 就会自动帮我们列出该对象有的方法,这里其实就是IDE使用了反射,通过对象找到该类对应的 Class 对象,从而就可以找到类中的属性和方法。
JDBC操作数据库第一步加载数据库驱动, Class.forName("com.mysql.jdbc.Driver"),这里是 MySQL 数据库,假如某一天我们想换成 Oracle 数据库,你可能会修改 forName() 方法中的参数为 Oracle 数据库驱动名。
做一个软件可以安装插件的功能,不知道插件的类型名称,你怎么实例化这个对象呢?所以无法在代码中 New出来 ,但反射可以,通过反射,动态加载程序集,然后读出类,检查标记之后再实例化对象,就可以获得正确的类实例。(写了一个程序,这个程序定义了一些接口,只要实现了这些接口的dll都可以作为插件来插入到这个程序中。就可以通过反射来实现。就是把dll加载进内存,然后通过反射的方式来调用dll中的方法。很多工厂模式就是使用的反射。)
项目应用
配置文件存放需要反射的类信息:
- 使用xml或者prop存keyvalue形式
- 添加一个这样的类,来专门存放需要反射的映射关系
public class Tables {public static final Map<String, String> tables = new HashMap<>();static {tables.put("PICRECORD", "com.stillcoolme.entity.PICRECORD");}
}
总结
反射可以使我们的代码更具灵活性(运行期类型的判断,动态类加载,动态代理(以后再聊这个)),但是反射也会消耗更多的系统资源,所以如果不需要动态创建一个对象,那么就不需要用到反射。
转载于:https://www.cnblogs.com/stillcoolme/p/9818573.html
Java知识系列 -- 反射相关推荐
- Java知识整理——反射
Java的反射机制是做什么的? 主要功能就是可以根据一个类的名称来创建一个类的实例,并调用实例的方法. 我们通常情况下创建一个类实例的方法,就是new ABC()这样的方式来创建,那为什么还要用反射绕 ...
- android 集成同一interface不同泛型_C# 基础知识系列- 10 反射和泛型(二)
0. 前言 这篇文章延续<C# 基础知识系列- 5 反射和泛型>,继续介绍C#在反射所开发的功能和做的努力.上一篇文章大概介绍了一下泛型和反射的一些基本内容,主要是通过获取对象的类型,然后 ...
- java 反射类 spring_学习Spring必学的Java基础知识(1)----反射
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...
- 视频教程-手写Java框架系列教程之一反射(含配套资料)-Java
手写Java框架系列教程之一反射(含配套资料) 张长志技术全才.擅长领域:区块链.大数据.Java等.10余年软件研发及企业培训经验,曾为多家大型企业提供企业内训如中石化,中国联通,中国移动等知名企业 ...
- Java注解与反射系列——Class类day1-3
Java注解与反射系列--Class类 Class类 常用方法 哪些类型有Class对象? 类的加载过程 类的加载 链接 初始化 什么时候会发送类的初始化 类的主动引用 类的被动引用 获取Class实 ...
- JAVA基础系列:反射
1. 定义 在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这 种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. ...
- 夯实Java基础系列9:深入理解Class类和Object类
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- 夯实Java基础系列22:一文读懂Java序列化和反序列化
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- 夯实Java基础系列15:Java注解简介和最佳实践
Java注解简介 注解如同标签 Java 注解概述 什么是注解? 注解的用处 注解的原理 元注解 JDK里的注解 注解处理器实战 不同类型的注解 类注解 方法注解 参数注解 变量注解 Java注解相关 ...
最新文章
- 云炬Qtpy5开发与实战笔记 1开发第一个桌面应用Hello World
- JavaFX maven工程pom文件完整内容
- 【小白学习keras教程】一、基于波士顿住房数据集训练简单的MLP回归模型
- 天空之城 matlab,[转载]matlab演奏《天空之城》代码
- mapper mysql 主键_实现通用mapper主键策略兼容mysql和oracle
- 网页设计作业作品成品HTML5+CSS大作业——简单的程序员个人博客(7页) 大学个人博客网页制作教程 表格布局网页模板
- Java大数运算(BigInteger BigDecimal)
- ArcGIS Model批量矢量裁剪矢量
- FPGA Nios II学习笔记一
- 路由器与交换机的区别是什么
- Java笔记 - 黑马程序员_07(多线程,线程同步,线程池,网络编程入门,UDP通信原理,TCP通信原理,commons-io工具类)
- NLP之分词技术理论
- 三菱FX系列PLC数据采集和点表自动侦测
- 等价多米诺骨牌对的数量
- 使用cryptsetup加密硬盘
- [转]关于GI/IR(我想理解这个应该具备一定财务知识才行)
- viewpager切页
- 根据邮箱查寻邮件系统
- 教你把gps服务器修改为中国加速搜星,手机导航-GPS搜星速度优化(android手机)...
- SQL Server多语句表值函数