我想定义一个使用具有多个边界的类型的函数,其中一个边界是另一个类型参数 . 例如:
<A, R extends A & SomeInterface> R doSomething(...);
似乎(根据Intellij IDEA)这是不允许的,也不是任何具有多个边界的类型,其中任何边界都是类型参数 . 所以这些都是非法的:
<A, R extends A & SomeInterface> R doSomething(...);
<A, B, R extends A & B> R doSomething(...);
但这些是合法的:
<R extends SomeType & SomeInterface> R doSomething(...);
<A, R extends A> R doSomething(...);
禁止扩展类型参数和接口的情况,但允许使用文字类型(类,枚举或接口)替换type参数 . 我会理解,如果不允许将类型参数作为边界,但事实并非如此 . 有什么我想念的吗?
如果这是一个xy问题,我试图解决的确切问题是:
public interface Functor<A, Self extends Functor<?, Self>>
{
<B, SelfB extends Self & Functor<B, Self>> SelfB map(Function<A, B> f);
}
上述声明,如果是合法的,似乎提供了足够的限制来解决this problem;确保返回类型是相同类型的仿函数,B作为其数据参数 . 这是扩展接口和由类型参数确定的其他类型的情况 .
1 回答
Java有这样的限制,因为不能保证
<A, R extends A & SomeInterface> R doSomething(...)
适用于所有泛型类型A
.想象一下有
SomeInterface
和AnotherInterface
:也许你已经看到了问题
想象一下,您执行
doSomething<..., AnotherInterface>(...)
R
类型现在应该同时具有void foo()
和String foo()
方法,这是由于签名冲突而无法实现的 .此外,我不确定是否会正确处理
doSomething<..., SomeInterface>(...)
案例:毕竟,接口不是其自身的子类型可能会有更多的问题,尽管一个反例足以证明一般规则不起作用
当您将特定类插入通用参数时,它可以工作,因为编译器能够推断您是否有冲突,这就是为什么
<R extends SomeType & SomeInterface> R doSomething(...)
是合法的