IncompatibleClassChangeError 异常引起的原因

在类加载过程中,分为以下几个阶段:
1. 加载
2. 验证
3. 准备
4. 解析
5. 初始化


验证分为
1. 文件格式验证 (验证字节流是否符合Class 文件格式的规范,并且能被当前版本的虚拟机处理)
2. 元数据验证 (对字节码描述信息进行语义分析,以保证其描述的信息符合Java语言规范要求)
3. 字节码验证 (整个验证过程中最复杂的一个阶段,主要目的是通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。)
4. 符号引用验证(对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验)

如果无法通过符号引用验证,那么就会抛出一个java.lang.IncompatibleClassChangeError 异常的子类
AbstractMethodError, IllegalAccessError, InstantiationError, NoSuchFieldError, NoSuchMethodError

实例验证

package com.example.lib.exception;
public class Parent {
    public final static String TAG = "haha";

    public void sayHello(){
        System.out.println("Hello World!");
    }
}
package com.example.lib.exception;
public class Child extends Parent{

    public static void main(String[] args){
        Child child = new Child();
        System.out.println("hello world!");
        child.sayHello();
    }
}

这个时候编译后直接运行,是可以通过的
然后我们将Parent 做下修改

package com.example.lib.exception;
public class Parent {
    public final static String TAG = "haha";

    //将sayHello的签名修改为private
    private void sayHello(){
        System.out.println("Hello World!");
    }
}

然后我们通过javac 编译Parent.java,将得到的Parent.class文件替换上个阶段产生的Parent.class文件。
然后运行带有main方法的child类,java com.example.lib.exception.child
这个时候我们就会得到如下异常

Exception in thread "main" java.lang.IllegalAccessError: tried to access method com.example.lib.exception.Parent.sayHello()V from class com.example.lib.exception.Child
        at com.example.lib.exception.Child.main(Child.java:12)

修改Parent.java为

package com.example.lib.exception;
public abstract class Parent {
    public final String TAG = "haha";

    public abstract void sayHello();

    public abstract void test();
}

报:

Exception in thread "main" java.lang.AbstractMethodError: com.example.lib.exception.Child.sayHello()V
        at com.example.lib.exception.Child.main(Child.java:12)

你可能感兴趣的:(java)