202108120641 - 类加载过程
我们能够通过一定的手段,覆盖 HashMap 类的实现么?
有哪些地方打破了 Java 的类加载机制?
如何加载一个远程的 .class 文件?怎样加密 .class 文件?
类加载过程
加载:
将.class文件加载到方法区。主要是从jar包或war包找到二进制数据并加载
验证:
将不符合规范的代码抛出java.lang.VerifyError,高版本的类库也无法加载。避免恶意代码攻击
准备:
在方法区为成员变量(包括普通和静态变量)分配内存,变量初始化。因为实例对象还没初始化,所以是在方法区完成的。
下面两段代码,code-snippet 1 将会输出 0,而 code-snippet 2 将无法通过编译。
这是因为局部变量不像类变量那样存在准备阶段。
类变量有两次赋初始值的过程,一次在准备阶段,赋予初始值(也可以是指定值);另外一次在初始化阶段,赋予程序员定义的值。
因此,即使程序员没有为类变量赋值也没有关系,它仍然有一个默认的初始值。但局部变量就不一样了,如果没有给它赋初始值,是不能使用的。
int a ;
public void out(){
System.out.println(a);
}
public static void main(String[] args) {
new Test().out();
}
code-snippet 1:
public class A {
static int a ;
public static void main(String[] args) {
System.out.println(a);
}
}
code-snippet 2:
public class A {
public static void main(String[] args) {
int a ;
System.out.println(a);
}
}
解析
- 类或接口的解析
- 类方法解析
- 接口方法解析
- 字段解析
我们来看几个经常发生的异常,就与这个阶段有关。
- java.lang.NoSuchFieldError 根据继承关系从下往上,找不到相关字段时的报错。
- java.lang.IllegalAccessError 字段或者方法,访问权限不具备时的错误。
- java.lang.NoSuchMethodError 找不到相关方法时的错误。
解析过程保证了相互引用的完整性,把继承与组合推进到运行时。
初始化
- static 语句块,只能访问到定义在 static 语句块之前的变量
- JVM 会保证在子类的初始化方法执行之前,父类的初始化方法已经执行完毕。
方法和 方法有什么区别?
- static 代码块只会执行一次,它对应的是
方法 - 在 new 一个新对象的时候,都会调用它的构造方法,就是
,用来初始化对象的属性。每次新建对象的时候,都会执行。