我试图在方法签名中实现类型保存,但类型关系是下限的。我似乎需要使用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
答案 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
对象,而不是添加它。)