Java 泛型方法约束 - 从约束中排除类型以防止删除问题?

标签 java generics type-constraints

我正在尝试重载基于类型约束的方法。代码看起来像这样:

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,只能向下转换为 AB

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/

相关文章:

java - 在java中下载包含内联图像的电子邮件正文

java - AWS Java SDK 凭证 linux ec2

haskell - 单子(monad)绑定(bind)的显式签名约束

java - 带有 `--multi-release` 选项的 jdeps 命令使用失败

java - JTable:如何获取表的更新列和行?

Java Generic - 找不到对象方法

java - 我怎样才能多次实现 Comparable ?

java - 如何使用 Spring 4 Autowiring 泛型类?

haskell - 带有约束的类型列表

Swift 的 pow() 函数不接受 Doubles 作为参数