“奇怪的例外”;无效的接收器类型类java.lang.Object;不是…的子类型;
我在使用jre1.8.0_66运行代码时遇到了这个奇怪的异常:“奇怪的例外”;无效的接收器类型类java.lang.Object;不是…的子类型;,java,java-8,java-stream,Java,Java 8,Java Stream,我在使用jre1.8.0_66运行代码时遇到了这个奇怪的异常: Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception at java.lang.invoke.CallSite.makeSite(CallSite.java:341) at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(Me
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
at main
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Object; not a subtype of implementation type interface Fruit
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
at java.lang.invoke.CallSite.makeSite(CallSite.java:302)
... 3 more
这是什么意思?代码如下:
public static interface Fruit {
int getPickingMonth();
}
public static class Apple implements Fruit, Serializable {
@Override
public int getPickingMonth() {
return 11;
}
}
public static class Orange implements Fruit, Serializable {
@Override
public int getPickingMonth() {
return 2;
}
}
public static void main(String[] args) {
List<Apple> apples = Arrays.asList(new Apple());
List<Orange> oranges = Arrays.asList(new Orange());
Stream.of(apples.stream(), oranges.stream())
.flatMap(Function.identity())
.map(Fruit::getPickingMonth) // exception occurs on this line
.forEachOrdered(System.out::println);
}
公共静态接口{
int getPickingMonth();
}
公共静态类Apple实现水果,可序列化{
@凌驾
public int getPickingMonth(){
返回11;
}
}
公共静态类Orange实现水果,可序列化{
@凌驾
public int getPickingMonth(){
返回2;
}
}
公共静态void main(字符串[]args){
List apples=Arrays.asList(new Apple());
List oranges=Arrays.asList(new Orange());
Stream.of(apples.Stream(),oranges.Stream())
.flatMap(函数.identity())
.map(水果::getPickingMonth)//此行发生异常
.forEachOrdered(System.out::println);
}
如果我将Fruit::getPickingMonth
更改为x->x.getPickingMonth()
,异常就会消失
值得一提的是:如果我从任何一个类中删除
Serializable
,异常也会消失。但是,如果我向这两个类添加另一个等效接口,例如,Cloneable
或某个自定义接口,则返回。我相信您只是试图从接口引用一个方法而不返回
即:
我想你会想要像这样的东西
Apple::getPickingMonth;
or
Orange::getPickingMonth;
反而
如果以上不是解决方案,则可能是一个强制转换问题,编译器不知道在字节码级别返回什么
在StackOverflow上有这样的问题
您遇到了与中讨论的相同的编译器错误 只要涉及交叉点类型,并且您使用的方法引用使用的接收器类型不是第一个(第一个类型是类型擦除后保留的类型),就会出现问题 因此,当您用lambda表达式替换方法引用时,您就不再受到bug的影响。如果从类型中删除可序列化的
,
,则流
的推断元素类型将是结果
,即不是交集类型,并且同样不会发生问题。但是,当两个元素类型实现了Fruit
和Serializable
时,编译器将推断元素类型Object&Fruit&Serializable
,原始类型将是Object
,这会在使用接收方类型Fruit
的方法引用时引发错误。您可以轻松解决此问题:
Stream.of(apples.stream(), oranges.stream())
.<Fruit>flatMap(Function.identity())
.map(Fruit::getPickingMonth) // no more exception on this line
.forEachOrdered(System.out::println);
实现同样的功能。这似乎与
javac
错误非常相关。感谢您的解释!我无法理解另外两个讨论,但这个答案非常简洁易懂。非常感谢!我已经用stream.of(enumClass.getEnumConstants()).map(EnumSuperInterface::getErrorCode))
替换了Arrays.stream(enumClass.getEnumConstants()).map(EnumSuperInterface::getErrorCode))
,它现在可以工作了!
Stream.of(apples.stream(), oranges.stream())
.<Fruit>flatMap(Function.identity())
.map(Fruit::getPickingMonth) // no more exception on this line
.forEachOrdered(System.out::println);
Stream.<Fruit>concat(apples.stream(), oranges.stream())
.map(Fruit::getPickingMonth) // no more exception on this line
.forEachOrdered(System.out::println);