9

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

请告诉我之间的确切区别:

ArrayList list = new ArrayList();

ArrayList<?> list = new ArrayList();

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

谢谢...

4

5 回答 5

6

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)编译器将生成警告,但不会阻止我将字符串添加到整数列表中。将方法更改为以下:

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

会阻止我做这样的手术。

于 2013-09-21T02:22:28.767 回答
4
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>();

在这种情况下,我们将任何对象添加到扩展Animal对象的列表中

或作为参数传递给方法。

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

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

于 2013-09-21T02:24:16.353 回答
1
ArrayList list = new ArrayList();

这是早于 java 泛型的非参数化容器。从中读出的对象通常必须被强制转换才能得到你想要的。

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

在这里,我们指定容器包含 String 对象。无需铸造即可读出。

<?>

是一个通配符参数,意思是“某事”,例如字符串、整数等。
请注意,这ArrayList<?> list = new ArrayList()是无效的语法;通常通配符将用于方法参数等。

于 2013-09-21T02:39:33.580 回答
1

行为没有区别。

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

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

@SJuan76 评论:

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

好吧,实际上你可以说那他们所做的。或者更准确地说,他们保留了旧形式,以便使用 Java 5+ 编译器继续编译旧的(Java 5 之前的)代码而不会出现编译错误。

于 2013-09-21T02:55:17.210 回答
0

数组列表 < ? > 表示未知类型的数组列表。它被称为通配符类型。

使用通配符,会发生以下情况

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

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

于 2013-09-21T02:28:43.343 回答