多个通用边界,包括类型参数

时间:2018-04-27 05:54:03

标签: java generics

我想定义一个使用具有多个边界的类型的函数,其中一个边界是另一个类型参数。例如:

<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 个答案:

答案 0 :(得分:1)

Java有这样的限制,因为不能保证 <A, R extends A & SomeInterface> R doSomething(...) 适用于所有泛型类型A

想象一下,有SomeInterfaceAnotherInterface

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(...)合法

的原因