Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
885 views
in Technique[技术] by (71.8m points)

lambda - Reason for the exception java.lang.VerifyError: Bad type on operand stack

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);
    }
}

If I remove the code

parentData = 1

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

Can any one tell the reason for this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Seems that such code should not compile at all. I minimized your code:

public class CompilerBug {
    int var = 0;

    public static void main(String[] args) {
        new CompilerBug().new Inner();
    }

    public class Inner {
        public Inner(Runnable r) {}

        public Inner() {
            this(() -> {
                var = 1;
            });
        }
    }
}

It's compiled without problems by javac 1.8.0.25, 1.8.0.40 and 1.9b57. Every compiled version produces the same output when launching:

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    CompilerBug$Inner.<init>(LCompilerBug;)V @3: invokedynamic
  Reason:
    Type uninitializedThis (current frame, stack[2]) is not assignable to 'CompilerBug$Inner'
  Current Frame:
    bci: @3
    flags: { flagThisUninit }
    locals: { uninitializedThis, 'CompilerBug' }
    stack: { uninitializedThis, 'CompilerBug', uninitializedThis }
  Bytecode:
    0000000: 2a2b 2aba 0003 0000 b700 04b1

        at CompilerBug.main(CompilerBug.java:5)

This code is not compiled by ECJ compiler. It reports a compilation error:

----------
1. ERROR in C:projectsTestsrcCompilerBug.java (at line 12)
    this(() -> {
         ^^^^^
Cannot refer to 'this' nor 'super' while explicitly invoking a constructor
----------
1 problem (1 error)

So it looks like a bug in javac compiler: it should return a compilation error instead (like ECJ).

I did not find similar bug in OpenJDK bug tracker, so submitted a new bug report via webform. If Java folks are reading this, the internal review ID assigned is JI-9021379.

Update: The bug report is accepted (JDK-8129740)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...