视频地址 动态类加载
学习这个东西得需要两个代码
Person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package org.example;
import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; public class Person implements Serializable{ public String name; private int age; public Person() { System.out.println("无参person"); } public static int id; static { System.out.println("静态代码块"); } public static void staticAction() { System.out.println("静态方法"); }
{ System.out.println("构造代码块"); } public Person(String name,int age) { System.out.println("有参person"); this.name=name; this.age=age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ",age=" + age + '}'; } private void action(String act) throws IOException { System.out.println(act); Runtime.getRuntime().exec("calc"); } private void readObject(ObjectInputStream ois) throws IOException,ClassNotFoundException { ois.defaultReadObject();; Runtime.getRuntime().exec("calc"); }
}
|
就是相较于以前多了(下面的三个东西)
在new一个无参对象的时候
在new一个有参对象的时候
是一样的
都是先静态代码块——-> 构造代码块 ——-> 有(无)参方法
当调用类的方法的时候,就不会调用其他关于对象的方法
这三个就是和对象相关的,所以不会调用
在调用这个静态变量的时候也调用了这个静态代码块
在类加载的时候是不会进行任何方法或者变量的调用的
上面的方法都是写死的,不能进行动态加载,所以这里我们就用到了之前在反射里面用到的方法 forName
就是这个方法进行了初始化的操作 (已知初始化操作会执行静态代码块)
然后跟进这个forName0的方法,这个方法是native写的,是c来写的
他里面有几个参数
第一个是传类名,第二个是判断是否初始化,第三个是类加载器,第四个不重要
因为forName里面默认的是否初始化是true,所以如果想让他不进行初始化的话,就传值,因为Class这个类里边还有另一个forName
因为ClassLoader是一个抽象类,不能实例化,但是他有个静态方法是可以实例化的
这里只传三个参数是因为forName只有三个参数,forName0才是有四个参数的
这样写就不能进行实例化和初始化了
我们可以利用反射里面学的newIntance()方法来进行实例化和初始化了
上面大概介绍完就开始讲这个类加载器的东西了
就是利用这个动态类加载来进行实例化对象(这里说明一下这个loadClass是不进行初始化的)
上面是简单的介绍,详细的看这篇文章 动态类加载