Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“奇怪的例外”;无效的接收器类型类java.lang.Object;不是…的子类型;_Java_Java 8_Java Stream - Fatal编程技术网

“奇怪的例外”;无效的接收器类型类java.lang.Object;不是…的子类型;

“奇怪的例外”;无效的接收器类型类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

我在使用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(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);