我想定义一个使用具有多个边界的类型的函数,其中一个边界是另一个类型参数。例如:
<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作为其数据参数。 这是扩展接口和由类型参数确定的其他类型的情况。
答案 0 :(得分:1)
Java有这样的限制,因为不能保证
<A, R extends A & SomeInterface> R doSomething(...)
适用于所有泛型类型A
。
想象一下,有SomeInterface
和AnotherInterface
:
public interface SomeInterface {
void foo();
}
public interface AnotherInterface {
String foo();
}
也许你已经看到了问题
想象一下你执行doSomething<..., AnotherInterface>(...)
R
类型现在应该同时具有void foo()
和String foo()
方法,由于签名冲突,这是不可能的。
此外,我不确定是否会正确处理doSomething<..., SomeInterface>(...)
案例:毕竟,接口不是其自身的子类型
可能存在更多问题,尽管一个反例足以证明一般规则不起作用
当您将特定类插入泛型参数时,它会起作用,因为编译器能够推断您是否有冲突,
这就是<R extends SomeType & SomeInterface> R doSomething(...)
合法