为什么我不能直接转换超级调用的结果?

时间:2020-06-11 09:25:38

标签: java generics inheritance functional-interface

所以我有一个扩展BiConsumer的接口。

@FunctionalInterface
public interface MyActionWithParameters<E, P> extends BiConsumer<Selection<E>, P> {
    @Override
    default MyActionWithParameters<E, P> andThen(BiConsumer<? super Selection<E>, ? super P> after) {
        var newAction = BiConsumer.super.andThen(after);
        return newAction::accept;
    }
}

这有效。

但是,如果我尝试return (MyActionWithParameters<>) BiConsumer.super.andThen(after);,则会收到类强制转换异常。

那是为什么?为什么我可以投射newAction::accept(即新的BiConsumer)而不是BiConsumer本身?我觉得答案应该很明显,但是我看不到。

编辑:完全错误

Caused by: java.lang.ClassCastException: class java.util.function.BiConsumer$$Lambda$2165/0x0000000840d10840 cannot be cast to class blah.blah.blah.MyFoo$MyActionWithParameters (java.util.function.BiConsumer$$Lambda$2165/0x0000000840d10840 is in module java.base of loader 'bootstrap'; blah.blah.blah.MyFoo$MyActionWithParameters is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @739fc679)

1 个答案:

答案 0 :(得分:4)

强制转换不起作用的原因是,无论BiConsumer.andThen返回什么,它都不会实现MyActionWithParametersBiConsumer(JDK接口)到底应该如何了解您自己的自定义接口? :-)

但是使用方法引用是可行的,因为通过使用方法引用,super.andThen返回的对象类型(也称为newAction)不再重要。重要的是方法-acceptaccept是否具有兼容的签名才能满足MyActionWithParameters的功能接口?是的,它可以正常工作。