最近发现自己忘了反射,赶紧写篇笔记来巩固一下。
反射的使用
反射的简单使用
反射是啥?
反射就是让你动态的操作Java语言,让你可以在程序运行的时候获取类的结构:属性,构造函数,方法等一切信息,并且操作这些信息。
反射api图解
要学会使用反射,直接围绕api进行
基本使用
因为这个有人总结的很好的,就不重复了,直接贴链接,去收藏那位大佬的博客吧
任意门→Java反射技术详解
获取Class对象的三种方法比较
总结
先直接来总结哈
在 Java API 中,获取 Class 类对象有三种方法:
第一种,使用 .class 方法。
这种方法只适合在编译前就知道操作的 Class。
Class clz = String.class;
第二种,使用 Class.forName 静态方法。
当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。
Class clz = Class.forName("java.lang.String");
第三种,使用类对象的 getClass() 方法。
String str = new String("Hello");
Class clz = str.getClass();
分析
先创建一个类,内部定义一些方法
public class Student{
static{
System.out.println("静态代码块执行");
}
{
System.out.println("构造代码块执行");
}
public Student(){
System.out.println("构造方法执行");
}
}
使用三种方式获取Student类的Class类
- 第一种方式:使用 .class 方法。
public class TestDemo {
public static void main(String[] args) {
System.out.println("======1======");
Class<Student> clazz1 = Student.class;
// Class<?> clazz1 = Student.class;
}
}
结果:
说明:JVM将使用类装载器,将类装入内存(前提是:类还没有装入内存),不做类的初始化工作,返回Class的对象。
- 第二种方法:使用 Class.forName 静态方法。
public class TestDemo {
public static void main(String[] args) throws ClassNotFoundException {
System.out.println("======2======");
Class<?> clazz2 = Class.forName("daycode.Student");
}
}
结果:
说明:装入类,并做类的静态初始化,返回Class的对象。
- 第三种方法:使用类对象的 getClass() 方法
public class TestDemo {
public static void main(String[] args){
System.out.println("======3======");
Class<? extends Student> clazz3 = new Student().getClass();
}
}
结果:
说明:对类进行静态初始化、非静态初始化;返回引用运行时真正所指的对象(子对象的引用会赋给父对象的引用变量中)所属的类的Class的对象。
Class对象
class对象是单例的?
如何判断是否是单例,测试一下就完事了(将就上面例子的代码)
public class TestDemo {
public static void main(String[] args) throws ClassNotFoundException {
Class<Student> clazz1 = Student.class;
Class<?> clazz2 = Class.forName("daycode.Student");
Class<? extends Student> clazz3 = new Student().getClass();
System.out.println(clazz1 == clazz2 && clazz2 == clazz3);
}
}
结果:
说明:三次获得的都是同一个Class对象
类加载过程
-
一个.java的文件经过javac命令编译成功后,得到一个.class的文件
-
当我们执行了初始化操作(有可能是new、有可能是子类初始化 父类也一同被初始化、也有可能是反射…等),会将.class文件通过类加载器装载到jvm中
-
将.class文件加载器加载到jvm中,又分了好几个步骤,其中包括 加载、连接和初始化
-
其中在加载的时候,会在Java堆中创建一个java.lang.Class类的对象,这个Class对象代表着类相关的信息。
更多关于类加载过程还是看别的大佬的博客吧,以后有时间自己更新
任意门👉JVM类加载过程
反射的应用:动态代理(未更)