当前位置:网站首页>反射(二)
反射(二)
2022-07-07 02:11:00 【Cold Snowflakes】
静态加载和动态加载
静态加载:编译时加载相关的类,如果没有找到则报错。
动态加载:运行时加载需要的类。
反射是动态加载,只有被执行到的时候,才会去加载类。
public class Main{
public static void main(String args[]) throws ClassNotFoundException{
// 静态加载, 编译的时候就要进行加载, 如果没找到就会报错, 依赖性很强
Cat cat = new Cat();
// 动态加载, 编译的时候不去管它, 也不会去检查 被加载的类是否存在
// 真正运行且执行到这段代码的时候才会去加载
Class.forName("com.itheima.Cat");
}
}
类加载
当程序要使用某个类时,如果该类还未被加载到内存,则系统会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化。
一般情况下,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载。
类的加载:JVM将字节码从不同的数据源(class文件,jar包,网络等等)转化为二进制字节流加载到内存中,并生成Class实例对象。
类的连接
验证阶段:确保 .class 文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身安全。
准备阶段:为static修饰的字段变量分配内存并且设置默认初始值,不包含用final修饰的static,因为final在编译的时候就会分配了。
解析阶段:主要将常量池中的符号引用替换为直接引用的过程。
类的初始化:类加载最后阶段,真正开始执行类中定义的Java程序代码,此阶段是执行 < clinit >()方法的过程。
< clinit >()方法是由编译器按语句在源文件中出现的顺序,依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句,并进行合并。
虚拟机会保证一个类的 < clinit >()方法在多线程环境中被正确地加锁,同步,如果多个线程同时去初始化一个类,则只会有一个线程去执行这个类的 < clinit >()方法,其他线程都需要阻塞等待,直到活动线程执行 < clinit >() 方法完毕。
若该类具有超类,则对其进行初始化,执行静态初始化器和静态初始化成员变量。
@SuppressWarnings({
"all"})
public class lambdademo {
public static void main(String[] args) {
System.out.println(fun.num);
}
}
/** * 在 Linking 的 Preparation 阶段, 对 num 分配内存,初始化为 0 * 在 Initialization 阶段, 收集 静态变量,静态代码块 至 <clinit> 方法中, 并执行 <clinit>方法 */
class fun {
static{
System.out.println("静态代码块被执行");
num = 300;
}
static int num = 100;
public fun(){
System.out.println("构造器被执行");
}
}
// Output
静态代码块被执行
100
// 分析结果, 可以明显地看到, 类加载中做了什么, 当然我们并没有去创建对象, 所以构造方法也没有被调用
// 大致的过程应该是这样
1. 加载 fun 类, 并生成对应的一份 Class实例, 以及在方法区中的 字节码二进制数据
2. Linking阶段, 为 num 分配内存,初始化为 0
3. Initialization阶段, 按在源文件中出现的顺序, 依次收集所有静态变量的赋值动作和静态代码块中的语句,合并至<clinit>方法中,并执行。
clinit() {
///静态代码块中的语句/
System.out.println("静态代码块被执行");
num = 300;
///静态变量赋值语句//
num = 100;
}
Field类的一些其他API
getModifiers(): default/0 , public/1 , private/2 , protected/4 , static/8 , final/16
// 可以使用 Modifier.toString(cls.getModifiers()) 将数字转为字符串
getType(): 返回一个 Class对象,表示属性的类型
getName(): 返回属性名
Class<fun> funClass = fun.class;
Field[] fields = funClass.getDeclaredFields();
for(Field f : fields){
System.out.println(f.getModifiers()); // 返回数值代表其访问权限修饰符
System.out.println(f.getType()); // int/double/java.lang.String ...
System.out.println(f.getName()); // 属性名
}
Mehod类
getModifiers() // 访问权限修饰符
getReturnType() // 返回Class对象,表示返回类型
getName() // 方法名
getParameterTypes() // 返回Class[], 表示参数类型数组
通过反射创建对象
Class<?> cls = Class.forName("com.itheima.fun");
// 1.使用无参构造器
Object o1 = cls.newInstance();
// 2.通过有参构造器(指定参数列表)
Constructor<?> cons1 = cls.getDeclaredConstructor(String.class);
Object o2 = cons1.newInstance("xxx");
// 3.也可以使用private的构造器
Constructor<?> cons2 = cls.getDeclaredConstructor(int.class, String.class);
cons2.setAccessible(true);
Object o3 = cons2.newInstance(100, "fang_shou_ba..");
Class对象的生成方式如下:
1、类名.class
JVM将使用类装载器, 将类装入内存,不做类的初始化工作,返回Class的对象。
2、Class.forName(“类的全限定名”)
装入类,并做类的初始化(会执行静态代码块和初始化静态变量),返回Class的对象。
平时使用 new 创建对象时,会先进行类加载,之后执行 非静态的代码块,之后执行构造函数。
几种生成Class实例方法的区别
边栏推荐
猜你喜欢
How to keep accounts of expenses in life
MySQL的安装
Which foreign language periodicals are famous in geology?
博士申请 | 上海交通大学自然科学研究院洪亮教授招收深度学习方向博士生
Rk3399 platform development series explanation (WiFi) 5.52. Introduction to WiFi framework composition
一段程序让你明白什么静态内部类,局部内部类,匿名内部类
CloudCompare-点对选取
开发者别错过!飞桨黑客马拉松第三期链桨赛道报名开启
Rk3399 platform development series explanation (WiFi) 5.53, hostapd (WiFi AP mode) configuration file description
Several key steps of software testing, you need to know
随机推荐
Apache ab 压力测试
js装饰器@decorator学习笔记
Wechat applet hides the progress bar component of the video tag
Etcd database source code analysis -- starting from the start function of raftnode
Performance comparison between Ceres solver and g2o
How can I check the DOI number of a foreign document?
Experience sharing of contribution of "management world"
HKUST & MsrA new research: on image to image conversion, fine tuning is all you need
蚂蚁庄园安全头盔 7.8蚂蚁庄园答案
LM小型可编程控制器软件(基于CoDeSys)笔记二十三:伺服电机运行(步进电机)相对坐标转换为绝对坐标
360 Zhiyu released 7.0 new products to create an exclusive "unified digital workspace" for the party, government and army, and central and state-owned enterprises
【从零开始】win10系统部署Yolov5详细过程(CPU,无GPU)
哈趣投影黑馬之姿,僅用半年强勢突圍千元投影儀市場!
JWT 认证
Rk3399 platform development series explanation (WiFi) 5.52. Introduction to WiFi framework composition
地质学类比较有名的外文期刊有哪些?
C语言整理(待更新)
Array proof during st table preprocessing
How to find the literature of a foreign language journal?
LM small programmable controller software (based on CoDeSys) Note 23: conversion of relative coordinates of servo motor operation (stepping motor) to absolute coordinates