当前位置:网站首页>反射(二)
反射(二)
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实例方法的区别
边栏推荐
- Performance comparison between Ceres solver and g2o
- string(讲解)
- JMeter function assistant - random value, random string, fixed value random extraction
- [start from scratch] detailed process of deploying yolov5 in win10 system (CPU, no GPU)
- 软件测试到了35岁,真的就干不动了吗?
- C语言面试 写一个函数查找两个字符串中的第一个公共字符串
- Pinduoduo lost the lawsuit: "bargain for free" infringed the right to know but did not constitute fraud, and was sentenced to pay 400 yuan
- Experience sharing of contribution of "management world"
- Programmers' daily | daily anecdotes
- Qtthread, one of many methods of QT multithreading
猜你喜欢
Redis(二)—Redis通用命令
ICML 2022 | explore the best architecture and training method of language model
PostgreSQL database timescaledb function time_ bucket_ Gapfill() error resolution and license replacement
LM11丨重构K线构建择时交易策略
[opencv] morphological filtering (2): open operation, morphological gradient, top hat, black hat
3531. Huffman tree
How to use wechat cloud hosting or cloud functions for cloud development of unapp development applet
进程间通信之共享内存
直击2022ECDC萤石云开发者大会:携手千百行业加速智能升级
LM小型可编程控制器软件(基于CoDeSys)笔记二十三:伺服电机运行(步进电机)相对坐标转换为绝对坐标
随机推荐
MySQL卸载文档-Windows版
ICML 2022 | 探索语言模型的最佳架构和训练方法
Pinduoduo lost the lawsuit: "bargain for free" infringed the right to know but did not constitute fraud, and was sentenced to pay 400 yuan
Open the blue screen after VMware installation
【解决】Final app status- UNDEFINED, exitCode- 16
LM small programmable controller software (based on CoDeSys) Note 23: conversion of relative coordinates of servo motor operation (stepping motor) to absolute coordinates
线性代数(一)
LM小型可编程控制器软件(基于CoDeSys)笔记二十三:伺服电机运行(步进电机)相对坐标转换为绝对坐标
dolphinscheduler3.x本地启动
如何解决数据库插入数据显示SQLSTATE[HY000]: General error: 1364 Field ‘xxxxx‘ doesn‘t have a default value错误
postgresql 数据库 timescaledb 函数time_bucket_gapfill()报错解决及更换 license
Which foreign language periodicals are famous in geology?
A program lets you understand what static inner classes, local inner classes, and anonymous inner classes are
dolphinscheduler3. X local startup
[SOC FPGA] custom IP PWM breathing lamp
程序员的日常 | 每日趣闻
string(讲解)
Rk3399 platform development series explanation (WiFi) 5.53, hostapd (WiFi AP mode) configuration file description
K8s running Oracle
Laravel uses Tencent cloud cos5 full tutorial