java反射
Java 反射
对于Class类的理解
注意,这里的Class和关键词class是两码事。这里的Class是一个类,它的实例就是我们平常使用的类如Person,Dog。如果说运行时类是对日常事物的一个抽象,Class可以理解为对运行时类类的进一步抽象。
创建Class的实例
调用运行时类的属性 .class
1 | Class<Person> clazz = Person.class; |
调用运行时类对象的getClass()
1 | Person person = new Person("Ando", 19); |
调用Class的静态方法:forName(String classPath)
1 | Class<?> clazz3 = Class.forName("Person"); |
这三种方法获取到的运行时类均为同一个
类加载过程
当程序使用到某个类,且该类还未被加载进内存中,则系统通过下列步骤对类进行初始化:
类的加载:将类的class文件转化为某种静态数据结构,存储在方法区,并为之在堆中创造一个java.lang.Class对象
类的链接:分为验证,准备,解析三个阶段。验证:元数据和字节码的验证(语法和语义的分析,确保该class对虚拟机安全)等验证机制。准备:为该类中定义的静态变量附0值。解析:将符号引用变为直接引用
类的初始化:为静态变量进行赋值
ClassLoader
类加载器作用是用来将类加载进内存的。JVM规范定义了如下类型的加载器:
引导类加载器:负责java核心平台库(如String等关键类),无法直接获取
拓展类加载器:负责jre/lib/ext目录下等jar包里的类
系统类加载器:负责自己定义的类
自下向上检查是类已经加载,自上向下尝试进行类加载
1 | ClassLoader classLoader = Person.class.getClassLoader(); |
创建运行时类对象
1 | Class<Person> personClass = Person.class; |
personClass.newInstance在jdk1.9之后被弃用,使用person.getDeclaredConstructor().newInstance()
使用该方法的要求:
- 运行时类必须提供空参的构造器
- 具有空参的构造器的访问权限
反射的动态性
利用反射我们可以在运行时根据不同的情况,为变量classPath赋不同的值,再用Class.forName(classPath)进行创建。这体现了反射的动态性。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ando's blog!