第十章——类加载器和反射
1、类的加载
类的加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
加载
就是指将class文件读入内存,并为之创建一个Class对象。
任何类被使用时系统都会建立一个Class对象。
连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化 就是我们以前讲过的初始化步骤
类初始化时机:
创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类
类加载器:
类加载器
负责将.class文件加载到内存中,并为之生成对应的Class对象。
虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
类加载器的组成
Bootstrap ClassLoader 根类加载器
Extension ClassLoader 扩展类加载器
Sysetm ClassLoader 系统类加载器
类加载器的作用:
Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
反射:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
获取构造方法
getConstructors
getDeclaredConstructors
创建对象
newInstance()
con.newInstance(“zhangsan", 20);
获取所有成员
getFields,getDeclaredFields
获取单个成员
getField,getDeclaredField
修改成员的值
set(Object obj,Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
获取所有方法
getMethods
getDeclaredMethods
获取单个方法
getMethod
getDeclaredMethod
暴力访问
method.setAccessible(true);
public class StudentDemo {
public static void main(String[] args) throws Exception{
Class<?> c1 = Class.forName("com.shujia.day20.Student");
Constructor<?> cons1 = c1.getConstructor();
Constructor<?> cons2 = c1.getDeclaredConstructor(String.class, String.class);
System.out.println(cons2);
Constructor<?> cons3 = c1.getDeclaredConstructor(String.class);
System.out.println(cons3);
Object o = cons1.newInstance();
System.out.println(o);
cons3.setAccessible(true);
Object o1 = cons3.newInstance("1001");
System.out.println(o1);
Field like = c1.getField("like");
Field id = c1.getDeclaredField("id");
like.set(o1, "骑自行车");
System.out.println(o1);
id.setAccessible(true);
id.set(o1,"1002");
System.out.println(o1);
Method fun1 = c1.getMethod("fun1");
System.out.println(fun1);
Method fun11 = c1.getMethod("fun1",String.class);
System.out.println(fun11);
Method fun3 = c1.getDeclaredMethod("fun3");
System.out.println(fun3);
fun1.invoke(o1);
fun3.setAccessible(true);
fun3.invoke(o1);
}
}
============================================================
public class Student {
private String id;
String name;
protected int age;
public String like;
public Student() {
}
private Student(String id) {
this.id = id;
}
Student(String id, String name) {
this.id = id;
this.name = name;
}
protected Student(String id, String name, int age, String like) {
this.id = id;
this.name = name;
this.age = age;
this.like = like;
}
public void fun1(){
System.out.println("这是公共的无参成员方法");
}
public void fun1(String s){
System.out.println("这是有参数成员方法"+s);
}
private void fun3(){
System.out.println("这是私有的无参成员方法");
}
private void fun3(String s){
System.out.println("这是私有的有参数成员方法"+s);
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
", like='" + like + '\'' +
'}';
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)