Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么类型的<&燃气轮机;在创建实例化列表时?_Java_List_Arraylist - Fatal编程技术网

Java 什么类型的<&燃气轮机;在创建实例化列表时?

Java 什么类型的<&燃气轮机;在创建实例化列表时?,java,list,arraylist,Java,List,Arraylist,我在多个不同的地方见过人们实例化列表或ArrayList,如: List<?> l = new ArrayList<>(); listl=newarraylist(); 是什么类型的??这是否意味着它可以容纳任何类型?如果是这样的话,为什么要使用它而不是just和ArrayList 这是否意味着它可以容纳任何类型 否。这意味着您的l变量可以引用任何类型的参数化列表。因此,这实际上是一个限制:您不允许向l添加任何对象,因为您不知道它接受哪些项。举一个具体的例子,l可以是

我在多个不同的地方见过人们实例化列表或ArrayList,如:

List<?> l = new ArrayList<>();
listl=newarraylist();
是什么类型的??这是否意味着它可以容纳任何类型?如果是这样的话,为什么要使用它而不是just和ArrayList

这是否意味着它可以容纳任何类型


否。这意味着您的
l
变量可以引用任何类型的参数化列表。因此,这实际上是一个限制:您不允许向
l
添加任何对象,因为您不知道它接受哪些项。举一个具体的例子,
l
可以是一个
列表
,也可以是一个
列表

,正如Marko正确指出的那样,这是对列表类型的未知限制

Java文档说:

使用通配符指定无界通配符类型 (?),例如,
列表
。这称为未知类型的列表。 有两种情况下,无界通配符非常有用 方法:

  • 如果您正在编写一个可以使用对象类中提供的功能实现的方法
  • 当代码在泛型类中使用不依赖于类型参数的方法时。例如,List.size或List.clear。 事实上,
    Class
    经常被使用,因为 类不依赖于T

让我给你讲一个长时间的睡前故事;读它入睡:)


让我们从这一点开始——要调用泛型方法,必须提供其类型参数。(除非以“原始”方式调用该方法,即以擦除形式调用,这是另一个主题:)

例如,要调用集合.emptyList(),必须提供
T
。它可以由程序员显式提供--

请记住,
仍然是由程序员隐式提供的


据推测,程序员是所有类型参数的无所不知的独裁者,编译器和程序员对何时可以省略类型参数以及何时可以从上下文推断类型参数有着共同的理解。当程序员省略类型参数时,他知道编译器可以根据严格的算法(他掌握的是:)准确地推断出他想要的类型参数 选择类型参数不是编译器的决定权,而是程序员的决定权,并将其传递给编译器

事实上,类型推断是如此复杂,几乎没有程序员知道在很多情况下会发生什么:)程序员更像是一个独裁者,发出模糊的命令,编译器会尽最大努力让它有意义。我们大多是凭直觉编写代码,而不是关注细节,并且我们有点相信,如果编译器批准,代码会达到我们想要的效果

在任何情况下,所有类型参数在编译时都是精确且可预测的固定参数。任何省略的类型参数都等效于显式指定的类型参数

某些类型参数是“不值得注意的”,例如捕获转换引入的类型变量。它们不能显式指定,只能进行推断。(尽管如此,程序员应该知道它们是什么,即使它们无法命名)


在前面的示例中,
T
只能推断为
String
,没有其他选择。但是在很多情况下,
T
有更多的候选者,类型推断算法必须有一个策略将其解析为候选者之一。例如,考虑这个孤独的陈述< /P>
    Collections.emptyList();
T
可以是任何类型
T
解析为
对象
,因为没有很好的理由将其解析为任何其他对象,例如
整数
字符串
等。
对象
更为特殊,因为它是所有对象的超类型


现在,让我们来讨论构造函数。从形式上讲,构造函数不是方法。但他们在很多方面非常相似。特别是,构造函数上的类型推断几乎与方法上的类型推断相同。调用类的构造函数的形式为
新类(args)

与方法一样,构造函数可以是泛型的,具有自己的类型参数。比如说,

class Bar
{
    <T>Bar(T x){ .. }
要为构造函数显式提供类型参数

    new <String>Bar("abc");
因为这已经有了不同的含义——调用“raw”
Foo
的构造函数

通过钻石推理,我们可以做一些在Java5/6中做不到的事情

List<Object> list = new ArrayList<>();  // Java 7. inferred: E=Object
// equivalent to
List<Object> list = new ArrayList<Object>(); // <Object> is required in Java 5/6
这里,推断出
E=Object
(还有什么?)。代码相当于

List<?> list = new ArrayList<Object>();
新类(args)
中的
类必须是具体类型。我们只能实例化特定元素类型的
ArrayList


但是变量
List
的声明类型
List
过于通用。对于局部变量,在IMO中最好以其更具体的类型声明它

ArrayList<Object> list = new ArrayList<>();
ArrayList list=new ArrayList();
不要在这里使用
,这只会让每个人都感到困惑

与此相关的一点是,很多人会支持“程序与界面对抗”

List List=new ArrayList();
^^^^  
这是错误的。我们在本地块中为谁提供抽象?在实现中使用最具体的类型以获得最大的清晰度; 在接口中使用抽象类型



zzzzzzzz

因此,它只能容纳一种类型,而您不知道它是什么。如果我理解正确,为什么这对任何人都有用?我真的看不出原因。它在方法签名中非常有用。比如说,
布尔hasPrimeNumberOfItems(列表)
——如果不能指定通配符,就不能将签名声明为所需的一般性签名。@MarkoTopolnik这与
方法(列表)
有何不同?很抱歉,如果语法有点错误,我不使用jav
class Foo<T>
{
    Foo(T x){ .. }
    new Foo<String>("");   // CLASS = Foo<String>
    new Foo<>("");   // inferred: T=String
     new Foo("");
List<Object> list = new ArrayList<>();  // Java 7. inferred: E=Object
// equivalent to
List<Object> list = new ArrayList<Object>(); // <Object> is required in Java 5/6
List<?> list = new ArrayList<>();
List<?> list = new ArrayList<Object>();
List<?> list = new ArrayList<?>();
                            ^^^
ArrayList<Object> list = new ArrayList<>();
     List<Object> list = new ArrayList<>();
     ^^^^