【问题标题】:Why can't I cast the result of the super call directly?为什么我不能直接投射 super 调用的结果?
【发布时间】:2020-06-11 09:25:38
【问题描述】:

所以我有一个扩展 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&lt;&gt;) 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)

【问题讨论】:

  • 这个接口有什么用途?除了超级界面之外,它似乎没有给你任何东西
  • @AndyTurner 好吧,有人决定引入一个额外的接口“以防我们需要扩展行为”和“强制语义封装”。到目前为止,我们还不需要扩展它,所以我相当肯定它是过度设计的,但我们现在坚持使用它,所以我添加了 andThen s.t.类型检查器接受myAction.andThen(...) 调用的结果。

标签: java generics inheritance functional-interface


【解决方案1】:

强制转换不起作用的原因是因为无论BiConsumer.andThen 返回什么,它都没有实现MyActionWithParameters。 JDK 接口BiConsumer 到底是怎么知道你自己的自定义接口的? :-)

但是使用方法引用是可行的,因为通过使用方法引用,super.andThen 返回的对象类型,也就是newAction,不再重要。重要的是方法 - acceptaccept是否有兼容的签名来满足MyActionWithParameters的功能接口?是的,它确实如此,所以它有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 2021-03-24
    相关资源
    最近更新 更多