我正在尝试重载基于类型约束的方法。代码看起来像这样:
protected static <T extends ComponentTemplate> void addComponent(List<ComponentTemplate> factors, T component)
{
...
}
protected static <T extends ComponentTemplate
& ConditionalComponent> void addComponent(List<ComponentTemplate> factors, T conditionalComponent)
{
....
}
ComponentTemplate
是抽象类,ConditionalComponent
是接口(interface)。这两个方法可以将组件添加到组件列表中。在组件实现 ConditionalComponent
的情况下,应该使用其他方法来确定是否应添加特定组件。当对象未实现 ConditionalComponent
时,将使用完全不同的方法。
问题是这些方法具有相同的删除(根据 RAD,当然拒绝编译它)。有没有办法定义第一个方法,使其排除任何扩展两者 ComponentTemplate
AND ConditionalComponent
的对象?我想象这样的事情:
protected static <T extends ComponentTemplate
& !ConditionalComponent> void addComponent(List<ComponentTemplate> factors, T component)
{
...
}
当然,那是行不通的(这不是有效的语法)。我尝试做的事情是否可行,或者是否有解决方法?
最佳答案
这是不允许的。为什么不呢?
在 Java 中调用方法时,将使用具有最具体类型签名的方法。
在例子中:
interface A {...}
interface B {...}
class X extends A, B {...}
void f(X);
void f(A);
void f(B);
X x = ...
f(x); // calls f(X)
f((A)x); // calls f(A)
f((B)x); // calls f(B)
我们都知道如何强制转换以调用我们想要的正确方法。
但是在例子中
<T extends X> void g(T); //G1
<T extends A & B> void g(T); //G2
g(x); // calls G1
我们可以调用G1
,但是没有重定向就无法调用G2
。
我们不能向下转换为 A & B
,只能向下转换为 A
或 B
。
A & B
似乎没有很好地集成到类型系统中(大多数人甚至都不知道),因此 Java 不认为 A
是在选择要分派(dispatch)的方法版本时,与 A & B
不同的类型。
疯狂的更多例子:
interface A
interface B extends A
<T extends A & B> void f(T)
<T extends B> void f(T)
这将编译,但你不能调用它们中的任何一个
B b = new B(){...}
f(B); // method reference is ambiguious.
关于Java 泛型方法约束 - 从约束中排除类型以防止删除问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23392586/