泛型:如何在使用super时获取重用类型?

时间:2014-01-10 16:34:58

标签: java generics

我试图在方法签名中实现类型保存,但类型关系是下限的。我似乎需要使用super T来限制方法参数受限制的类型。但我无法将传递的类型传播到方法的输出参数。

基本上这就是我想要的:

class Bar {}

class Foo<T extends Bar> {

    // this works perfectly
    public <S extends T> Foo<S> from(S bar) {
        return new Foo<>(bar);
    }

    // incorrect syntax!
    // this should convert the current Foo into a Foo for a sub class ONLY
    public <U super T> Foo<U> fooing(Class<U> clazz) { // <-- this is what I need
        return new Foo<>(clazz);
    }
}

可悲的是,这是不正确的语法。 super只能与前面的通配符运算符?一起使用。

我能得到的最接近的是:

public <U extends Bar> Foo<U> fooing(Class<? extends T> clazz) {...}

但它有一些不良影响:

class Bar2 extends Bar {}
...
Foo<Bar2> shouldFail = fooBar.fooing(Bar.class);  // Bar != Bar2
Foo<? extends Bar2> shouldFail2 = fooBar.fooing(Bar.class); // Bar does not extend Bar2

以上陈述有效。但是我希望它们在编译时失败。 关于如何实现我的需求的任何想法?

这是一个小提琴: http://ideone.com/scBFLc

1 个答案:

答案 0 :(得分:1)

正如Java Generics FAQ指出并且你经历过,这对于类方法来说是不可能的。

FAQ提供的解决方法是使用静态方法:

public static <A extends Bar, B extends A> Foo<A> upcast(
        Foo<B> from, Class<A> target) { }

但是我只能回应其他评论员的担忧:你正在为一些严重的维护问题做好准备,特别是因为我无法想象这件作品的实际用例(与FAQ的例子相反)只处理Foo对象,而不是添加它。)