异常 java.lang.VerifyError 的原因:操作数堆栈上的类型错误 [英] Reason for the exception java.lang.VerifyError: Bad type on operand stack

查看:26
本文介绍了异常 java.lang.VerifyError 的原因:操作数堆栈上的类型错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The below simple java code sends the java.lang.VerifyError: Bad type on operand stack exception

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

B的构造函数中,不会出现异常.

from B's constructor, the exception won't come.

谁能告诉我这是什么原因?

Can any one tell the reason for this?

推荐答案

出现问题是因为你的 lambda 表达式没有引用 thisthis 的成员,而是一个成员外部 this.你有没有像

The problem arises because your lambda expression does not reference this or a member of this but a member of the outer this. Had you written class B like

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

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

the compiler rejected it without any doubts as accessing innerData implies accessing this.

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

The point about the outer instance is that it is a constant which is even available when the inner instance has not been fully constructed yet. So it’s correct to accept the code but unfortunately the compiler generates code which attempts to access the outer instance via an implicit field of the inner class instance, thus the lambda expression requires an instance of the inner class and attempting to use the not fully constructed inner class instance produces the error.

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

It can be easily demonstrated that the code can be compiled correctly:

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

有了这个小改动,lambda 表达式就引用了外部实例,而无需访问内部实例,也不会出现错误.

with that small change, the lambda expression refers to the outer instance without accessing the inner instance and no error arises.

这篇关于异常 java.lang.VerifyError 的原因:操作数堆栈上的类型错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆