java findclass_带你深入了解Class类-深度分析:反射从入门到精通
1. Class 类的原理
孟子曰:得人心者得天下。而在 Java 中,这个「人心」就是Class 类,获取到Class类我们就可以为所欲为之为所欲为。下面让我们深入「人心」,去探索 Class 类的原理。
首先了解 JVM 如何构建实例。
1.1 JVM 构建实例
JVM:Java Virtual Machine,Java 虚拟机。在JVM中分为栈、堆、方法区等,但这些都是JVM内存,文中所描述的内存指的就是JVM内存。.class文件是字节码文件,是通过.java文件编译得来的。
知道上面这些内容,我们开始创建实例。我们以创建 Person 对象举例:
Person p = new Person()
简简单单通过new就创建了对象,那流程是什么样的呢?见下图
这也太粗糙了一些,那在精致一下吧。
同志们发现没有,其实这里还是有些区别的,我告诉你区别是下面的字比上面多,你会打我不(别打我脸)。
粗糙的那个是通过new创建的对象,而精致的是通过ClassLoader操作 .class文件生成Class类,然后创建的对象。
其实通过new或者反射创建实例,都需要Class对象。
1.2 .class 文件
.class文件在文章开头讲过,是字节码文件。.java是源程序。Java 程序是跨平台的,一次编译到处执行,而编译就是从源文件转换成字节码文件。
字节码无非就是由 0 和 1 构成的文件。
有如下一个类:
通过 vim 查看一下字节码文件:
这啥玩意,看不懂。咱也不需要看懂,反正JVM对.class文件有它自己的读取规则。
1.3 类加载器
还记得上面的精致图中,我们知道是通过类加载器把.class文件加载到内存中。具体的类加载器内容,我会另写一篇文章讲解(写完链接会更新到这里)。但是核心方法就是 loadClass(),只需要告诉它要加载的name,它就会帮你加载:
protected Class> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 1.检查类是否已经加载
Class> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
// 2.尚未加载,遵循父优先的等级加载机制(双亲委派机制)
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// 3.如果还没有加载成功,调用 findClass()
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
// 需要重写该方法,默认就是抛出异常
protected Class> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
类加载器加载.class文件主要分位三个步骤
检查类是否已经加载,如果有就直接返回
当前不存在该类,遵循双亲委派机制,加载 .class文件
上面两步都失败,调用 findClass()
因为 ClassLoader 的 findClass 方法默认抛出异常,需要我们写一个子类重新覆盖它,比如:
@Override
protected Class> findClass(String name) throws ClassNotFoundException {
try {
// 通过IO流从指定位置读取xxx.class文件得到字节数组
byte[] datas = getClassData(name);
if (null == datas){
throw new ClassNotFoundException("类没有找到:" + name);
}
// 调用类加载器本身的defineClass()方法,由字节码得到 class 对象
return defineClass(name, datas, 0, datas.length);
}catch (IOException e){
throw new ClassNotFoundException("类没有找到:" + name);
}
}
private byte[] getClassData(String name) {
return byte[] datas;
}
defineClass 是通过字节码获取 Class 的方法,是 ClassLoader 定义的。我们具体不知道如何实现的,因为最终会调用一个 native 方法:
private native Class> defineClass0(String name, byte[] b, int off, int len,
ProtectionDomain pd);
private native Class> defineClass1(String name, byte[] b, int off, int len,
ProtectionDomain pd, String source);
private native Class> defineClass2(String name, java.nio.ByteBuffer b,
int off, int len, ProtectionDomain pd,
String source);
总结下类加载器加载 .class文件的步骤:
通过ClassLoader类中loadClass() 方法获取Class
从缓存中查找,直接返回
缓存中不存在,通过双亲委派机制加载
上面两步都失败,调用findClass()
通过 IO 流从指定位置获取到 .class文件得到字节数组
调用类加载器defineClass() 方法,由字节数组得到Class对象
1.4 Class 类
.class文件已经被类加载器加载到内存中并生成字节数组,JVM根据字节数组创建了对应的Class对象。
接下来我们来分析下Class对象。
我们知道 Java 的对象会有下面的信息:
权限修饰符
类名和泛型信息
接口
实体
注解
构造函数
方法
这些信息在 .class文件以 0101 表示,最后 JVM 会把.class文件的信息通过它的方式保存到Class中。
在Class中肯定有保存这些信息的字段,我们来看一下:
Class类中用ReflectionData里面的字段来与.class的内容映射,分别映射了字段、方法、构造器和接口。
通过annotaionData映射了注解数据,其它的就不展示了,大家可以自行打开IDEA查看下Class的源码。
那我们看看Class类的方法
1.4.1 构造器
Class类的构造器是私有的,只能通过JVM创建Class对象。所以就有了上面通过类加载器获取Class对象的过程。
1.4.2 Class.forName
Class.forName()方法还是通过类加载器获取Class对象。
1.4.3 newInstance
newInstance()的底层是返回无参构造函数。
2. 总结
我们来梳理下前面的知识点:
反射的关键点就是获取Class类,那系统是如何获取到Class类?
是通过类加载器ClassLoader将.class文件通过字节数组的方式加载到JVM中,JVM将字节数组转换成Class对象。那类加载器是如何加载的呢?
通过ClassLoader的loadClass()方法
从缓存中查找,直接返回
缓存中不存在,通过双亲委派机制加载
上面两步都失败,调用findClass()
通过 IO 流从指定位置获取到 .class文件得到字节数组
调用类加载器defineClass() 方法,由字节数组得到Class对象
Class类的构造器是私有的,所以需要通过JVM获取Class。
Class.forName()也是通过类加载器获取的Class对象。newInstance方法的底层也是返回的无参构造函数。
java findclass_带你深入了解Class类-深度分析:反射从入门到精通相关推荐
- 火爆B站的阿玮老师,他带着课程走来了(含4天入门到精通Java直播课)
他来啦.他来啦 终于把百万B站用户都爱的阿玮老师盼来啦! 此处应该有掌声 如果你是B站资深用户 相信早就耳闻阿玮老师的大名啦 阿玮老师在B站有多受欢迎,你往下康康~~ 这究竟是什么神仙老师呀 来啦就出 ...
- Java设计模式之中介者模式(UML类图分析+代码详解)
大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...
- Java设计模式之享元模式(UML类图分析+代码详解)
大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...
- Jva编解码,加密工具类大全(Base64编解码,URL 编解码,sha56_Hmac加密,MD5对字符串进行加密,java自带类实现SHA-256方式加密)
Base64编解码 /*** Base64编码.*/public static String encodeBase64(byte[] input) {return new String(Base64. ...
- 【java】java自带的java.util.logging.Logger日志功能
偶然翻阅到一篇文章,注意到Java自带的Logger日志功能,特地来细细的看一看,记录一下. 1.Java自带的日志功能,默认的配置 ①Logger的默认配置,位置在JRE安装目录下lib中的logg ...
- Java自带的常用工具
2019独角兽企业重金招聘Python工程师标准>>> 引言 在日常代码使用中,我们经常遇到判断字符串为空,或者集合为空的操作.例如判断集合为空,我的第一反应是list.size() ...
- c mysql封装 jdbc_利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现
最近看老罗的视频,跟着完成了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完成对数据库的增删改查.其中查询这块,包括普通的查询和利用反射完成的查询,主要包括以下几个函数接口 ...
- java同步锁synchronized_Java对象锁和类锁全面解析(多线程synchronized关键字)
本文主要是将synchronized关键字用法作为例子来去解释Java中的对象锁和类锁.特别的是希望能帮大家理清一些概念. 一.synchronized关键字 synchronized关键字有如下两种 ...
- java源程序可以有几个主类_Java源程序是由类定义组成的,每个程序可以定义若干个类,但只有一个类是主类。_学小易找答案...
[填空题]分析以下程序的执行结果 #include using namespace std; class Sample { int x; int y; public: Sample(int a,int ...
最新文章
- 服务器巡检文档,服务器巡检工具
- 合并两个有序链表—leetcode21
- CMake with WinMinGW
- 360私有云平台-HULK 5岁啦~
- 双刃剃须刀行业调研报告 - 市场现状分析与发展前景预测
- css补充、JavaScript、Dom
- vue项目eslint配置
- VMWare安装Win10虚拟机详细教程
- 语音社交系统源码中实时音频常见问题分析和解决:延时和抖动
- 东方联盟郭盛华发家史:8年来实现跨越式发展
- 【转载】Unity3D研究院之静态自动检查代码缺陷与隐患
- hackthebox - blunder (Bludit渗透cewl使用 sudo提权)
- 1. 制作满屏水印(PS)
- 裁员潮下,你需要这 10 大神器
- 【无标题】sap-ecc6.0 ides 安装过程记录
- RMAN CROSSCHECK命令 说明
- 智慧养殖远程管理监控方案
- hadoop批量安装第三方包
- Carsim软件使用技巧
- 不管怎样,苹果公司仍然是全球最有价值的公司
热门文章
- android root 挂载分区,adb — adb disable-verity, adb remount 实现重新挂载system分区为可读写分区...
- 记一次线上Java程序导致服务器CPU占用率过高的问题排除过程
- 区块链软件公司:区块链使用程序如何成为战胜商场应战的垫脚石
- 基于NFS实现lamp的负载均衡之二: 部署NFS服务器
- pip安装lxml报错
- 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]
- 二叉树的建立和遍历算法 - 数据结构和算法47
- wcf http 返回图片
- 【转载】开源且免费软件包分类列表
- 一个IT人士的个人经历,给迷失方向的朋友