在使用Java中的泛型时,我有点不方便。请考虑以下代码:
/**
* MyElement class is simply a wrapper for a generic object.
*/
public static class MyElement<T> {
public final T OBJ;
public MyElement(T obj) {
this.OBJ = obj;
}
}
/**
* MyElementList contains an array list of MyElements of the given type, T.
* This represents a class that uses a list of MyElements of a certain type,
* and this list can be accessed in an unmodifiable format.
*/
public static class MyElementList<T> {
//Properties
private List<MyElement<T>> elementList = new ArrayList();
//CTOR
public MyElementList(List<MyElement<T>> initElements) {
elementList.addAll(initElements);
}
//Getter
public List<MyElement<T>> getElements() {
return Collections.unmodifiableList(elementList);
}
}
public static void main(String[] args) {
//New list of elements
//Notice that I did not explicitly specify the type for 'MyElement'
List<MyElement> theElements = new ArrayList(Arrays.asList(
new MyElement[] {
new MyElement("E 1"),
new MyElement("E 2"),
new MyElement("E 3")
}
));
//Also notice I did not explicitly specify the type for 'MyElementList'
MyElementList theList = new MyElementList(theElements);
//The following does not work.
//It seems to not work because theList.getElements() returns a 'List'
//not necessarily a 'List<MyElement>' which is what I would expect it to
//return...
//Why???
for(MyElement e : theList.getElements()) {
System.out.println(e.OBJ.toString());
}
//Currently my work around is to do the following, but I do not like
//having to introduce another variable, and I would rather just do the
//one above
List<MyElement> listOfElements = theList.getElements();
for(MyElement e : listOfElements) {
System.out.println(e.OBJ.toString());
}
//How come the first 'for-each' loop method does not work?
//Is there anyway I could get it to work?
//THANK YOU!
}
在main方法中,如果我没有为'MyElementList'指定类型参数,'getElements()'方法只返回'List',而不是'List&lt; MyElement&gt;'。这很不方便,因为如果我想迭代每个'MyElement',我需要引入另一个变量作为临时列表,如代码所示。
我使用的IDE是Netbeans 7.2
提前致谢!
编辑
谢谢大家的快速回复。我对这里的社区印象非常深刻。我得出以下结论:
再次感谢!
答案 0 :(得分:2)
如果您将MyElementList
更改为
public static class MyElementList<T extends MyElement> {
//Properties
private List<T> elementList = new ArrayList<T>();
//CTOR
public MyElementList(List<T> initElements) {
elementList.addAll(initElements);
}
//Getter
public List<T> getElements() {
return Collections.unmodifiableList(elementList);
}
}
它应该有用。
编辑泛型可以看作是Java中的编译时提示,因为Java擦除会将泛型转换为Object。如上所述更新类将告诉编译器仅扩展MyElement
符合列表的元素,for(MyElement e : theList.getElements())
将起作用。
编辑2 正如其他人所指出的那样(对不起,我乍看之下并没有看到它)也将原始声明更改为:
MyElementList<MyElement> theList = new MyElementList<MyElement>(theElements);
答案 1 :(得分:1)
而不是使用
for(MyElement e : theList.getElements()) {
System.out.println(e.OBJ.toString());
}
你可以使用
for (Iterator<MyElement> it = theList.getElements().iterator(); it.hasNext();) {
MyElement e = it.next();
System.out.println(e.next().OBJ.toString());
}
使您的编译符合规。
但我更愿意在实例化/访问它们时指定类所需的类型(以及您的编译器,我猜;)
)。
答案 2 :(得分:1)
首先不起作用,因为getElements
为原始类型
List<?>
第二个有效,因为您将其分配给List<MyElement>
,忽略了警告。忽略是可以的,因为你知道它包含什么,但编译器没有。
答案 3 :(得分:0)
为什么
getElements()
方法不返回List<MyElement>
因为输入了MyElement
!
没有对
MyElementList
进行重大更改 我能做些什么来解决这个问题?
您可以使用通配符:
List<MyElement<?>> someList = getElements();