定义没有特定类型的集合

时间:2011-09-12 15:01:48

标签: java collections

    public static void main(String[] args) {
       Set vals = new TreeSet();
       vals.add("one");
       vals.add(1);
       vals.add("two");
       System.out.println(vals);
}

(i) - 定义一个集合而不给它一个类型意味着什么?出于什么目的 这是为了吗?

(ii) - 我可以用任何方式为集合添加不同的类型吗?

这是一个例子 - 虽然它警告我,但没有编译错误。

但是,除了例外,还有一个运行时错误。

4 个答案:

答案 0 :(得分:2)

  1. 使用原始类型调用定义集合(或任何类型化的类)而不指定类型参数。它仅存在 以实现向后兼容性,不应在新代码中使用。如果有效地删除了泛型对类型的所有影响。
  2. 通常,您可以将自己的设置定义为接受Object:然后它会接受所有值:Set<Object> vals = new HashSet<Object>()但是这对TreeSet无效,因为它需要彼此的值Comparable如果你想要将任意类型添加到同一个TreeSet(这通常是一些架构问题的迹象,即设计气味),那么你需要实现自己的{{ 3}}可以比较任意元素并将其传递给Comparator

答案 1 :(得分:1)

i)这意味着它可以有任何对象。如果要添加任何类型。 (通常是设计问题)

ii)使用类型擦除,你可以。

  

但是,除了例外,还有一个运行时错误。

在编译时获取错误通常比获取运行时错误更好。 (更容易找到并修复)

答案 2 :(得分:1)

Upto Java 1.4没有Generics。所有集合只能包含Object,并且在将对象从集合中取出后,您必须对该对象进行转播。所以你会这样做

Set vals = new Treeset();
String s = (String)vals.get(0);

而不是

Set<String> vals = new Treeset<String>();
String s = vals.get(0);

放置不同类型的没有共享接口或超类的对象是非常糟糕的做法,因为当你从集合中取出它时你不知道如何处理它。

答案 3 :(得分:1)

private Set<JPanel> s1;

public void run() {
    aMethod(s1);
}

/* line 7 */ public void aMethod(Set panels) {

}

如果通过将第7行更改为

来重构上述代码
public void aMethod(Set<Object> panels) {

它将不再编译。如果你将该行重构为

public void aMethod(Set<?> panels) {

它仍然会像以前一样编译,作为额外奖励,你将不再拥有“Set is raw ...”警告