异常 java.lang.VerifyError: Bad type on operand stack 的原因

2024-03-11

下面的简单java代码发送java.lang.VerifyError:操作数堆栈上的类型错误例外

public class TestJavaCodes {

    int parentData = 0;

    public void init() {
        A ob = new B();
    }

    public static void main(String[] args) {

        TestJavaCodes testJavaCodes = new TestJavaCodes();
        testJavaCodes.init();
    }

    public static class A {
        public A(MyLambdaFunc lambdaFunc) {
        }
    }

    public class B extends A {

        public B() {
            super((data1, type) -> {
                parentData = 1;
            });
        }
    }

    @FunctionalInterface
    public static interface MyLambdaFunc {
        public void onData(String data, int type);
    }
}

如果我删除代码

parentData = 1

from B的构造函数,异常不会出现。

谁能说出其中的原因吗?


出现问题是因为您的 lambda 表达式没有引用this或 的成员this但其中的一员outer this。你写过课吗B like

public class B extends A {
    int innerData;
    public B() {
        super((data1, type) -> innerData = 1);
    }
}

编译器毫无疑问地拒绝了它,因为它正在访问innerData意味着访问this.

关于外部实例的一点是,它是一个常量,甚至在内部实例尚未完全构造时也可用。因此,接受代码是正确的,但不幸的是,编译器生成的代码尝试通过内部类实例的隐式字段访问外部实例,因此 lambda 表达式需要内部类的实例并尝试使用未完全构造的内部类类实例产生错误。

可以很容易地证明代码can正确编译:

public class B extends A {
    public B() {
        this(TestJavaCodes.this);
    }
    private B(TestJavaCodes outer) {
        super((data1, type) -> outer.parentData = 1);
    }
}

通过这个小小的更改,lambda 表达式引用外部实例而不访问内部实例,并且不会出现错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

异常 java.lang.VerifyError: Bad type on operand stack 的原因 的相关文章

随机推荐