Java 泛型 : Multiple Inheritance in Bounded Type Parameters <T extends A & I>

标签 java generics types bounded-wildcard

我将要创建一个工厂,它创建某种类型 T 的对象,它扩展了某个类 A 和另一个接口(interface) I。但是,T 一定是未知的。以下是最低限度的声明:

public class A { }
public interface I { }

这是工厂方法:

public class F {
    public static <T extends A & I> T newThing() { /*...*/ }
}

编译一切正常。

当我尝试使用以下方法时,效果很好:

A $a = F.newThing();

...虽然这不是:

I $i = F.newThing();

编译器提示:

Bound mismatch: The generic method newThing() of type F is not applicable for the arguments (). The inferred type I&A is not a valid substitute for the bounded parameter

我不明白为什么。明确指出“newThing 返回某种类型 T 的东西,它确实扩展了类 A 并实现了接口(interface) I”。当分配给 A 时一切正常(因为 T 扩展了 A)但分配给 I 却不行(因为什么?,显然返回的东西既是 A 又是 一个 I)

另外:当返回一个对象时,假设类型为 class B extends A implements I 的 B,我需要将其转换为返回类型 T,尽管 B 匹配边界:

<T extends A & I> T newThing() {
    return (T) new B();
}

但是,编译器不会抛出任何类似 UncheckedCast 之类的警告。

因此我的问题是:

  • 这里出了什么问题?
  • 有没有一种方法可以轻松实现所需的行为(即分配给静态类型 A 或 I 的变量),就像在工厂方法中通过强制转换解决返回类型问题一样?
  • 为什么分配给 A 有效,而分配给 I 却不行?

--

编辑:这里是完全使用 Eclipse 3.7 的完整代码片段,为 JDK 6 设置的项目:

public class F {
    public static class A { }
    public static interface I { }

    private static class B extends A implements I {  }

    public static <T extends A & I> T newThing() {
        return (T) new B();
}

    public static void main(String... _) {
        A $a = F.newThing();
        // I $i = F.newThing();
    }
}

编辑:这是一个包含方法和调用的完整示例,在运行时运行:

public class F {
    public static class A {
        int methodA() {
            return 7;
        }
    }
    public static interface I {
        int methodI();
    }

    private static class B extends A implements I {
        public int methodI() {
            return 12;
        }
    }

    public static <T extends A & I> T newThing() {
        return (T) new B();
    }

    public static void main(String... _) {
        A $a = F.newThing();
        // I $i = F.newThing();
        System.out.println($a.methodA());
    }
}

最佳答案

关于第二个问题:

考虑这种情况:

 class B extends A implements I {}
 class C extends A implements I {}

现在,以下使用类型推断:

<T extends A & I> T newThing() {
  return (T) new B();
}

所以你可以这样称呼:

C c = F.newThing(); //T would be C here

T 可以是 任何 扩展 AI 你不能只返回一个B 的实例。在上面的例子中,转换可以写成(C)new B()。这显然会导致异常,因此编译器会发出警告:Unchecked cast from B to T - unless you're supressing those warnings.

关于Java 泛型 : Multiple Inheritance in Bounded Type Parameters <T extends A & I>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9824831/

相关文章:

java - PersistenceException - 当多个 @OneToMany 关系与同一实体时抛出 org.hibernate.exception.ConstraintViolationException

java - 如何在 Xamarin 中获取 AccessibilityManager 实例

generics - Swift 泛型和 CMutableVoidPointer

java - 具有可比较项目的通用列表java

types - 动态找出结构体内部内容的好方法是什么?

java - 虚拟机/云上的 Sun Java 实时系统

java - 类文件中的内部类但不在类主体中?

C# Language : generics, open/closed, bound/unbound, constructed

swift - UIColor 如何成为 Swift 中的类型?

haskell - 编写 Haskell 程序来对用命令式编程语言编写的程序进行类型检查