Weird exception “Invalid receiver type class java.lang.Object; not a subtype of …”

前端 未结 2 1409
暗喜
暗喜 2020-12-08 16:12

I\'m getting this strange exception in code run using jre1.8.0_66:

Exception in thread \"main\" java.lang.BootstrapMethodError: call site initialization exce         


        
相关标签:
2条回答
  • 2020-12-08 16:56

    I believe you are just trying to reference a method from the interface with no return.

    ie:

    Fruit::getPickingMonth; //cant return anything
    

    I would imagine you would want something like

    Apple::getPickingMonth;
    or
    Orange::getPickingMonth;
    

    Instead

    If the above isn't the solution it might be a casting issue where the compiler doesn't know what to return on the bytecode level.

    There are questions like this on StackOverflow

    Lambda Referencing

    Lambda Conversion Exception

    0 讨论(0)
  • 2020-12-08 16:57

    You ran into the same compiler bug that has been discussed in this question and that question.

    The problem occurs whenever an intersection type is involved and you are using a method reference using a receiver type other than the first one (the first type is the one that will remain after type erasure).

    So when you replace the method reference with a lambda expression, you are not affected by the bug anymore. If you remove the Serializable from the types instead, the inferred element type of the Stream will be Fruit, i.e. not an intersection type, and again the problem does not occur. But with the two element types implementing Fruit and Serializable, the compiler will infer the element type Object&Fruit&Serializable and the raw type will be Object which provokes the error when using a method reference with the receiver type Fruit. You can easily work around this:

    Stream.of(apples.stream(), oranges.stream())
            .<Fruit>flatMap(Function.identity())
            .map(Fruit::getPickingMonth) // no more exception on this line
            .forEachOrdered(System.out::println);
    

    The compiled code will be identical to your original, but the formal result type of the flatMap operation will be Stream<Fruit>, ignoring all other artifacts of the inferred intersection type. As a consequence the method reference Fruit::getPickingMonth will implement the type Function<Fruit,Integer> instead of Function<Object&Fruit&Serializable,Integer> and the compiler bug does not materialize.

    But note that your code is unnecessarily complicated. You can simply use

    Stream.<Fruit>concat(apples.stream(), oranges.stream())
            .map(Fruit::getPickingMonth) // no more exception on this line
            .forEachOrdered(System.out::println);
    

    to achieve the same.

    0 讨论(0)
提交回复
热议问题