Rus*_*ett 9 java generics nested-generics type-parameter
这是一个我编写的实例代码的简化示例,所以如果它有点做作,我会道歉.我想要做的是从单个嵌套类型参数中有效地获取两个类型参数.我很确定这是不可能的,但我想我会试一试.
//Not legal java code
public class Foo<C extends Collection<T>> { //where T is another type parameter
private C coll;
public Foo(C coll) {
this.coll = coll;
}
public void add(T elem){
this.coll.add(elem);
}
//UPDATED TO ADD GETTER
/**
* I may need to retrieve the collection again, or pass it
* on to another function that needs the specific C type
*/
public C getColl(){
return coll;
}
}
...
List<String> strings = new ArrayList<String>();
Foo<List<String>> foo = new Foo<List<String>>(strings);
foo.add("hello");
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过添加另一个类型参数来实现:
public class Foo<C extends Collection<T>,T>
Run Code Online (Sandbox Code Playgroud)
但后来我必须添加冗余:
Foo<List<String>,String> foo = new Foo<List<String>,String>(strings);
Run Code Online (Sandbox Code Playgroud)
在我的真实案例中,我的泛型有时可以在implements子句中指定
public class Bar implements Baz<String>
Run Code Online (Sandbox Code Playgroud)
必须指定第二个类型参数然后更加痛苦,因为它感觉它会在我的脸上抛出实现细节.不得不说
Foo<Bar,String>
Run Code Online (Sandbox Code Playgroud)
当String和Bar之间已经存在关系时,看起来似乎不够优雅.我得到它的Java,所以这与领域一致,但只是好奇,如果有一个解决方案.
这是不可能的,我不认为它是理想的,因为你现有的课程中没有任何东西需要不变性.
Foo<T,C extends Collection<T>>
Run Code Online (Sandbox Code Playgroud)
可能更普遍
Foo<T,C extends Collection<? super T>>
Run Code Online (Sandbox Code Playgroud)
如果有T的唯一原因是允许变异的集合.
注意,如果您担心必须经常指定两个类型参数,则可以创建一个浅子类:
class DerivedFoo<T> extends Foo<Collection<T>,T>
Run Code Online (Sandbox Code Playgroud)
并且您可以使用工厂方法来避免在创建时双重指定
public static <T> Foo<Collection<T>,T> fromCollection(Collection<T> c)
Run Code Online (Sandbox Code Playgroud)
您还可以将界面抽象为一个,interface
以获得DerivedFoo
上面提到的简洁类型的好处.