Java 原始类型与<;之间的差异&燃气轮机;仿制药

Java 原始类型与<;之间的差异&燃气轮机;仿制药,java,generics,collections,Java,Generics,Collections,也许有人会问,但我找不到 请告诉我以下两者之间的确切区别: ArrayList list = new ArrayList(); 及 ArrayList list=new ArrayList(); 我搞不清楚这两者的确切区别是什么 谢谢…ArrayList仅表示“任何类型”。换句话说,任何类型的ArrayList都可以分配给该变量。可以是ArrayList,ArrayList或其他任何内容。仅使用通配符,而不使用关键字super(后跟类型),意味着您无法向定义为ArrayList的列表中添加任

也许有人会问,但我找不到

请告诉我以下两者之间的确切区别:

ArrayList list = new ArrayList();

ArrayList list=new ArrayList();
我搞不清楚这两者的确切区别是什么

谢谢…

ArrayList
仅表示“任何类型”。换句话说,任何类型的
ArrayList
都可以分配给该变量。可以是
ArrayList
ArrayList
或其他任何内容。仅使用通配符,而不使用关键字super(后跟类型),意味着您无法向定义为
ArrayList
的列表中添加任何内容<但是,code>ArrayList单独表示旧式类型less
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
现在,如果我调用
insert(ints)
编译器将生成一个警告,但不会阻止我向整数列表中添加字符串。将方法更改为以下内容:

void insert(List<?> list) {
   // loop through list, do whatever you like
   list.add("my string"); // compiler error on this dangerous operation
}
void插入(列表){
//循环浏览列表,做任何你喜欢的事情
list.add(“my string”);//此危险操作的编译器错误
}
会阻止我做这样的手术

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");
ArrayList list=new ArrayList();
列表。添加(“测试”);
更新

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

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

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

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

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
Collection c=newarraylist();
c、 添加(新对象());//编译时错误
如果没有通配符,您可以向数组中添加任意内容

ArrayList list = new ArrayList();
这是java泛型之前的非参数化容器。从中读取的对象通常必须进行强制转换才能获得所需的内容

ArrayList<String> list = new ArrayList<String>();
ArrayList list=new ArrayList();
这里我们指定容器保存字符串对象。无需浇铸即可读出


是一个通配符参数,表示字符串、整数等“某物”。

请注意,
ArrayList list=new ArrayList()
是无效语法;通常,通配符将用于方法参数等。

在行为上没有区别

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

请注意,
通配符语法不能用于需要确定类型的情况

@SJuan76评论道:

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


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

你说得对。但是他们之间的行为有什么不同呢?若唯一的区别是我们不能向ArrayList中添加任何内容,那个么在什么情况下我们需要它?这可以用作只读列表。假设您需要将不同的列表传递给只对其执行读取操作的函数。使用此语法可以执行此操作。但是,如果将集合作为旧的无类型集合传递,则可能会对集合执行一些非法操作。如果将泛型集合用作非泛型集合,编译器会警告您这一点。使用语法,编译器将保护您的列表(请参阅我的编辑)。您不会回答他的问题。他在问,一个带有通配符的列表和另一个带有原始对象(没有泛型)的列表有什么区别?也许你应该解释一下导致编译错误的
的含义(我想他们添加该功能不是为了得到一些产生编译错误的代码).它主要用于函数调用签名。这是一个非常复杂的问题;佩克斯。在foo()中,不允许添加对象,对吧,但可以在列表上迭代,例如,-for(Object-Object:list){System.out.println(Object);}它不是无效的,而是将泛型与原始类型混合在一起。Hmmm的可能重复存在差异。那么从类中剥离所有泛型信息,从而可能绑定到不同的方法呢。尽管我还没有检查ArrayList是否有可以进行不同绑定的方法。
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
ArrayList list = new ArrayList();
ArrayList<String> list = new ArrayList<String>();
<?>