当前位置:网站首页>反射(二)
反射(二)
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实例方法的区别
边栏推荐
- 直击2022ECDC萤石云开发者大会:携手千百行业加速智能升级
- 面试中有哪些经典的数据库问题?
- 哈趣投影黑马之姿,仅用半年强势突围千元投影仪市场!
- Navicat导入15G数据报错 【2013 - Lost connection to MySQL server during query】 【1153:Got a packet bigger】
- Markdown 并排显示图片
- Experience sharing of contribution of "management world"
- rt-thread 中对 hardfault 的处理
- ICML 2022 | 探索语言模型的最佳架构和训练方法
- Rk3399 platform development series explanation (WiFi) 5.53, hostapd (WiFi AP mode) configuration file description
- You don't know the complete collection of recruitment slang of Internet companies
猜你喜欢

Three updates to build applications for different types of devices | 2022 i/o key review

MySQL的安装

dolphinscheduler3.x本地启动

Can't you really do it when you are 35 years old?

A very good JVM interview question article (74 questions and answers)

2022 Android interview essential knowledge points, a comprehensive summary

LM11丨重构K线构建择时交易策略

3531. Huffman tree

Developers don't miss it! Oar hacker marathon phase III chain oar track registration opens

POI导出Excel:设置字体、颜色、行高自适应、列宽自适应、锁住单元格、合并单元格...
随机推荐
"Parse" focalloss to solve the problem of data imbalance
C语言面试 写一个函数查找两个字符串中的第一个公共字符串
Several key steps of software testing, you need to know
Ha Qu projection dark horse posture, only half a year to break through the 1000 yuan projector market!
K8s running Oracle
Developers don't miss it! Oar hacker marathon phase III chain oar track registration opens
rt-thread 中对 hardfault 的处理
Performance comparison between Ceres solver and g2o
Find duplicate email addresses
C interview 24 (pointer) define a double array with 20 elements a
Symmetric binary tree [tree traversal]
请问如何查一篇外文文献的DOI号?
mobx 知识点集合案例(快速入门)
LM小型可编程控制器软件(基于CoDeSys)笔记二十三:伺服电机运行(步进电机)相对坐标转换为绝对坐标
vim映射大K
uniapp开发小程序如何使用微信云托管或云函数进行云开发
微信小程序隐藏video标签的进度条组件
雷特智能家居龙海祁:从专业调光到全宅智能,20年专注成就专业
程序员的日常 | 每日趣闻
隐马尔科夫模型(HMM)学习笔记