Java 类型 & 反射
2021-07-29 本文已影响0人
bowen_wu
类 & Class
- RTTI => Run-Time Type Identification => 运行时类型识别 => 任何一个对象在任何时刻都可以知道自己是什么类型的 =>
Object.getClass()
- 一个 Class 对象就是一个类的说明书 => JVM 根据这个说明书创建出来一个类的实例
- 静态属性就是 Class 对象上的属性 =>
static
属性归属于当前对象
Class 对象的生命周期
类 | Class 对象 在第一次被使用时被加载
![](https://img.haomeiwen.com/i9617841/ad21472128fb013f.png)
在初始化之后,.class
文件就放在了元空间中
Classloader
Classloader 负责从外部系统中加载一个类
- 这个类对应的 Java 文件不一定需要存在
- 这个字节码
.class
并不一定需要存在 => 文件 => 字节流 => 可以从任何地方获取 => 动态加载 => 动态字节码增强
双亲委派加载模型
每个 Class
都有一个 Parent,当一个 Classloader 加载一个类的时候,会首先使用 Parent 的 loadClass
![](https://img.haomeiwen.com/i9617841/bf82db3bafe8895a.png)
任何一个类加载器被要求加载类会查看自己的 Parent,如果 Parent 有了,则不会尝试自己去加载
优点:JDK 内置的类都是由最顶端的启动类加载器加载的 => 保障安全 => 恶意的类没有办法加载
Java 语言规范 & JVM 规范
- Java Language Specification => JLS => 代码是否合法
- Java Virtual Machine Specification => JVMS => 字节码如何在 JVM 上运行、对象如何生成等等
Java 和 JVM 没有关系,唯一的联系是字节码,但是字节码可以不由 Java 生成 => 分离提供了在 JVM 上运行其他语言的可能
反射 Reflection
一个类可以看到自己的方法 | 属性
java.lang.Class
根据参数动态创建一个对象 => Class.forName
public static void main(String[] args) {
String classname = args[0]; // 全限定类名
Class c = Class.forName(classnames);
Object obj = c.getConstructor().newInstance(); // c.newInstance() Java9 被废弃了 => 可扩展性 => 使用 c.getConstructor().newInstance()
}
java.lang.reflect.Method
根据参数动态调用一个方法 => Method => Method.invoke
public static void main(String[] args) {
Cat cat = new Cat();
cat.getClass().getMethod(args[0]).invoke(cat)
}
java.lang.reflect.Field
根据参数动态获取一个属性 => Field => Field.get
public static void main(String[] args) {
Cat cat = new Cat();
cat.getClass().getField(args[0]).get(cat)
}
知识点
- JVM 中存放
.class
的地方是元空间 => 异常 =>OutOfMemory:PermGen
=> 类出现问题 - 在 IDE 中运行一个
Main
=> IDE 将.java
文件编译,并将编译后的文件放在target/classes
中 => 拼装一个命令行,执行该Class
对象的Main
方法 - 运行 Java 的命令可以添加一个
-verbose
=> 可以打印出很多日志,方便 debugger =>-verbose:class
/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/bin/java -verbose:class -javaagent:/Applications/IntelliJ\ IDEA.app/Contents/lib/idea_rt.jar=60444:/Applications/IntelliJ\ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/lib/tools.jar:/Users/BowenWu/bowen/user/Java/binary-tree-dfs-bfs/target/classes com.github.hcsp.algorithm.BinaryTree
- 文件的本质是字节流
-
javap
命令可以查看字节码 =>javap <file>