原始类型与泛型中的<! - ? - >之间的区别

时间:2013-09-21 02:11:41

标签: java generics collections

可能会在某个地方询问,但我找不到它。

请告诉我:

之间的确切区别
ArrayList list = new ArrayList();

ArrayList<?> list = new ArrayList();

我无法弄清楚这两者之间的确切区别。

...谢谢

5 个答案:

答案 0 :(得分:5)

ArrayList<?>仅表示“任何类型”。换句话说,任何类型的ArrayList都可以分配给这样的变量。这可能是ArrayList<Integers>ArrayList<JButton>或其他任何内容。单独使用通配符,不使用关键字super(后跟类型),意味着您不能添加任何内容到定义为ArrayList<?>的列表。但是,仅ArrayList表示旧的样式类型ArrayList,您可以执行各种操作,包括add

List<?> list;
List<Integer> ints = new ArrayList<Integer>();
List<Integer> strings = new ArrayList<Integer>();
list = ints; // valid
list = strings; // valid
list.add("new"); // compile error

<强>更新

假设我有以下方法:

void insert(List list) {
   // loop through list, do whatever you like
   list.add("my string"); // dangerous operation 
}

现在,如果我调用insert(ints)编译器将生成警告,但不会阻止我将String添加到整数列表中。将方法改为以下:

void insert(List<?> list) {
   // loop through list, do whatever you like
   list.add("my string"); // compiler error on this dangerous operation
}

会妨碍我做这样的操作。

答案 1 :(得分:3)

ArrayList list = new ArrayList();

我们声明一个可以接受任何类型对象的数组列表。

例如:

list.add(new Dog());
list.add(new Person());
list.add("Test");

ArrayList<?> list = new ArrayList();

我们使用泛型声明一个数组列表,可以使用通配符接受任何对象

这里的问题是我们无法向该数组列表中添加元素。

此代码甚至不会编译:

ArrayList<?> list = new ArrayList();
list.add("test");

<强>更新

我认为唯一的目的是什么?泛型中的通配符将由extends关键字耦合。

ArrayList<? extends Animal> list = new ArrayList<Dog>();

在这种情况下,我们将任何对象添加到列表,以扩展动物对象

或作为参数传递给方法。

public void foo(List<?> list) { }

在这种情况下,方法 foo 无法将对象添加到参数列表

答案 2 :(得分:1)

ArrayList list = new ArrayList();

这是一个早于java泛型的非参数化容器。从中读出的对象通常必须被投射以获得你想要的东西。

ArrayList<String> list = new ArrayList<String>();

这里我们指定容器包含String对象。读出不需要铸造。

<?>

是一个通配符参数,意思是“某些东西”,如String,Integer等。
请注意ArrayList<?> list = new ArrayList()语法无效;通常,通配符将用于方法参数等。

答案 3 :(得分:1)

行为没有区别。

真正的区别在于编译器对待它们的方式。在第一种情况下,您告诉编译器“将其视为原始类型”,并且不要尝试进行任何通用的静态类型。在第二种情况下,您说“将其视为泛型类型”...但实际的类型参数是“我们希望避免在此处指定的某种类型”。

请注意,在需要明确类型的情况下,不能使用<?>通配符语法。

@ SJuan76评论道:

  

“(我猜他们没有添加该功能只是为了让一些代码产生编译错误)”

嗯,实际上你可以说他们做了。或者更确切地说,他们离开旧表单,以便旧的(Java 5之前的)代码将继续使用Java 5+编译器编译而不会出现编译错误。

答案 4 :(得分:0)

ArrayList&lt; ? &GT;表示未知类型的数组列表。它被称为通配符类型。

使用外卡,会发生以下情况

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error

如果没有通配符,您可以将任何您喜欢的内容添加到数组中