JAVA反射与类加载机制转载

原创
小哥 3年前 (2022-10-27) 阅读数 42 #大杂烩

版权声明:本文是博客作者的原创文章,全文如下。 CC 4.0 BY-SA 版权协议,转载请附上原始来源链接和本声明。
指向本文的链接:https://blog.csdn.net/lym3lavender/article/details/102700869
JAVA反射和类加载机制
JAVA反射
动态语言
反射机制
浅谈反射的应用
JAVA反射API
反射使用步骤
获取Class对象
通过反射创建对象
JVM类加载机制
类加载的生命周期
类加载器
双亲委托模式
JAVA反射
动态语言
动态语言:程序可以在运行时改变结构,可以引入新的函数,可以删除现有的函数和其他结构变化。
从反思的角度看JAVA属于半动态语言。
反射机制
java反射机制:在运行状态下,你可以知道任何类的所有属性和方法,对于任何对象,你可以调用它的任何方法和属性。这个动态获取信息和动态调用对象方法的函数被调用Java反射机制。

浅谈反射的应用
编译时类型:由声明对象时使用的类型确定。
运行时类型:由实际分配的对象类型决定。
当程序在运行时需要发现对象和类的真实信息,而不能在编译时预测对象和类属于哪些类时,可以通过反射来获取要运行的类和对象的真实信息。
JAVA反射API
反射API用来生成JVM有关中的类、接口或对象的信息。
API包括Class类、Field类、Method类、Constructor类等。
Class类:反映核心类,可以获取类的属性、方法等信息。
Field类:Java.lang.reflec包中的类,表示可用于获取和设置类中属性值的类的成员变量。
Java.lang.reflec包中的类,表示可用于获取类中的方法信息或执行方法的类的方法。
Constructor类: Java.lang.reflec包中的类表示类的构造方法。
反射使用步骤
获取实例化的对象和反射方法:

获取要对其进行操作的类。Class对象,Class对象任意调用类的方法。
调用Class类中的方法。
通过反射API操作信息。
获取Class对象
调用对象的getClass()方法
Person p=new Person();
Class clazz=p.getClass();
1
2
叫一个班级。class属性以获取相应的类。Class对象
Class clazz = Person.class;
1
使用Class类中的forName()静态方法
Class clazz = Class.forName("类的完整路径");
1
示例:

Class clazz=Class.forName("reflection.Person");
//获取Person类的所有方法信息。
Method[] method=clazz.getDeclaredMethods();
for(Method m:method){
System.out.println(m.toString());
}
//获取Person类的所有成员属性信息。
Field[] field=clazz.getDeclaredFields();
for(Field f:field){
System.out.println(f.toString());
}
//获取Person类的所有构造方法信息。
Constructor[] constructor=clazz.getDeclaredConstructors();
for(Constructor c:constructor){
System.out.println(c.toString());
}

通过反射创建对象
Class对象的newInstance()
这种方法要求Class与该对象对应的类具有默认的空构造函数。
Constructor对象的newInstance()
先使用Class该对象获取指定的Constructor对象
再调用Constructor对象的newInstance()方法来创建 Class与类对应的对象的实例
通过这种方式,您可以选择创建实例的构造方法。
JVM类加载机制
类加载的生命周期
JVM类加载机制分为加载、验证、准备、解析和初始化五个部分。让我们分别看看这五个过程。

Load:通过类的权限名获取该类的二进制字节流,将字节流表示的静态存储结构转换为运行时数据结构,并在运行中生成类。Class对象作为访问入口点。
验证:文件格式验证、元数据验证、字节码验证、符号引用验证等,确保Class文件字节流中包含的信息是否符合当前虚拟机的要求,且不危及虚拟机本身的安全。
准备:为类变量分配内存,并设置类变量的初始值。
解析:虚拟机将常量池符号引用替换为直接引用的过程。
符号引用:一组符号描述被引用的目标,而不考虑由虚拟机实现的布局。引用的目标不必加载到内存中。
直接引用:直接指向目标的指针、相对偏移量或句柄。
初始化:执行构造函数方法的过程。该方法是由编译器自动收集类中类变量的赋值操作和静态语句块中的语句形成的。如果没有对类中的静态变量或静态语句块赋值,则编译器不能生成()方法。
以下情况将初始化类
遇到new、getStatic、putStatic、imokeStatic和其他字节码指令。也就是说,使用new,读取静态字段,调用静态字段。
使用reflect包的方法是对类的反射调用。
初始化父类未初始化的类。
指定要执行的主类
jdk1.7动态语言支持,MethodHandle实例
在以下情况下不执行类初始化
通过子类引用父类的静态字段。
定义对象数组
常量在编译期间存储在调用类的常量池中。
按类名获取Class对象
通过Class.forName()如果指定了参数,则加载指定的类。initialize为false
通过ClassLoader默认的loadClass方法
类加载器
将加载操作放在JVM外部实现,以便应用程序决定如何获取所需的类。
启动类加载器(Bootstrap ClassLoader):负责装车 JAVA_HOME\lib 在目录中,或通过-Xbootclasspath参数在路径中指定,并由虚拟机识别(由文件名标识,如rt.jar)的类。
扩展类加载器(Extension ClassLoader):负责装车 JAVA_HOME\lib\ext 在目录中,或通过java.ext.dirs系统变量指定路径中的类库。
应用程序类加载器(Application ClassLoader):负责装车用户路径(classpath类库打开。
JVM通过双亲委托模式进行类的加载,当然我们也可以通过继承java.lang.ClassLoader实现一个定制的类加载器。


双亲委托模式
当类收到类加载请求时,它不会首先尝试加载类本身,而是将请求委托给父类来完成。只有当父类加载器反馈它无法完成请求时,子类加载器才会尝试加载自己。

三次破坏双亲委托模式
JDK1.2发布前
JNDI服务(线程上下文加载器)
用户对程序动态的追求,OSGi动态模型系统
OSGi动态模型系统
动态变化结构
OSGi服务平台提供在多种网络设备上无需重启的动态变化结构功能,为了最小化耦合度和促使这些耦合度可管理,OSGi技术提供了面向服务的体系结构,使这些组件能够动态发现彼此。
模块化编程和热插拔
OSGi旨在实现Java为程序的模块化编程提供了基本条件,基于。OSGi很可能程序可以实现模块级热插拔功能,当程序升级更新时,只能停用、重装再启动部分程序,这对于企业级程序开发非常有吸引力。
它提供了强大的功能,但也引入了额外的复杂性,因为它不符合类加载的双父委托模型。

————————————————
版权声明:本文是CSDN博主“Alalella”的原文如下 CC 4.0 BY-SA 版权协议,转载请附上原始来源链接和本声明。
原始链接:https://blog.csdn.net/lym3lavender/article/details/102700869

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门