我正在尝试编写一个具有泛型成员变量的类,但它本身并不是通用的.具体来说,我想说我有一个"可以实现与自身相似的某种类型"的值列表,因此我可以在该列表上调用sort ...我希望这是有道理的.
我正在尝试做的最终结果是创建一个类,以便我可以使用(任何给定类型)的数组创建所述类的实例,并让它为该列表生成字符串表示.在实际代码中,我还传入了我传入的类的类:
String s = new MyClass(Integer.class, 1,2,3).asString();
assertEquals("1 or 2 or 3", s);
String s = new MyClass(String.class, "c", "b", "a").asString();
assertEquals("\"a\" or \"b\" or \"c\"", s);
Run Code Online (Sandbox Code Playgroud)
最初我甚至不想传入类,我只想传递值并让代码检查结果数组以选择值的类......但这也给了我麻烦.
以下是我的代码,但是我无法想出适合变量类型的mojo.
public class MyClass {
// This doesn't work as T isn't defined
final List<T extends Comparable<? super T>> values;
public <T extends Comparable<? super T>> MyClass (T... values) {
this.values = new ArrayList<T>();
for(T item : values) {
this.values.add(item);
}
}
public <T extends Comparable<? super T>> List<T> getSortedLst() {
Collections.sort(this.values);
return this.values;
}
}
Run Code Online (Sandbox Code Playgroud)
变量声明行出错:
Syntax error on token "extends", , expected
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感谢.
编辑:更新的代码使用List而不是数组,因为我不确定它是否可以用数组完成.
@Mark:从我读过的所有内容来看,我真的想说"T是一种与自身相当的类型",而不仅仅是"T是一种可比的类型".话虽如此,以下代码也不起作用:
public class MyClass {
// This doesn't work
final List<? extends Comparable> values;
public <T extends Comparable> MyClass (T... values) {
this.values = new ArrayList<T>();
for(T item : values) {
this.values.add(item);
}
}
public <T extends Comparable> List<T> getSortedLst() {
Collections.sort(this.values);
return this.values;
}
}
Run Code Online (Sandbox Code Playgroud)
添加行错误:
The method add(capture#2-of ? extends Comparable) in the type List<capture#2-of ? extends Comparable> is not applicable for the arguments (T)
Run Code Online (Sandbox Code Playgroud)
排序行错误:
Type mismatch: cannot convert from List<capture#4-of ? extends Comparable> to List<T>
Run Code Online (Sandbox Code Playgroud)
结论:
它似乎归结为Java无法完全处理我想做的事情.问题是因为我想说的是:
我想要一个与自己相当的项目列表,然后我从创建时传入的数据中立即创建整个列表.
但是,Java看到我有那个列表并且无法确定我的情况的所有信息在编译时都可用,因为我可以尝试稍后将内容添加到列表中,由于类型擦除,它不能保证安全.在不将泛型类型应用于类的情况下,无法向Java传达我的情况所涉及的条件.
我认为简单的答案是你不能那样做.如果某个类属性的类型取决于类型参数,则必须在类级别声明该参数.而且我认为它没有任何其他方式"有意义".
如果T在您的示例中不是类的类型参数,那么它是什么?它不能是方法的类型参数,因为该类型由方法的调用方式决定.(如果在具有不同推断类型的不同静态上下文中调用该方法,则属性声明的上下文中的T名义类型是T什么?)
因此,为了使这回到你想要做的事情,一个实例MyClass将保存某种类型的元素,并且你希望能够以静态类型安全的方式插入和删除元素.但与此同时,你不想说出那种类型.那么编译器应该如何静态地区分MyClass保存(比方说)Integer对象的实例和保存String对象的实例呢?
我甚至认为你不能用明确的动态类型检查来实现它.(我认为类型擦除意味着该getSortedList()方法的实现无法找出绑定到其返回类型的实际类型.)
不.真正的解决方案是创建MyClass一个声明类型参数的泛型类T; 例如
public class MyClass <T extends Comparable<T>> {
Run Code Online (Sandbox Code Playgroud)
并T从两个方法中删除方法级类型参数的声明.