我正在尝试使用以下方式创建List实例:
List<String> listOne = new ArrayList<String>();
List<String> listTwo = new ArrayList<String>(){};
List<String> listThree = new ArrayList<String>() {{}};
只有listOne
被初始化为java.util.ArrayList
,但listTwo
和listThree
不是。
在初始化listTwo和listThree以及如何更好地理解它时会发生什么?
我的测试示例如下:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> listOne = new ArrayList<String>();
List<String> listTwo = new ArrayList<String>(){};
List<String> listThree = new ArrayList<String>() {{}};
System.out.printf("listOne.getClass() == listTwo.getClass() is %b \n",
listOne.getClass() == listTwo.getClass());
System.out.printf("listOne.getClass() == listThree.getClass() is %b \n",
listOne.getClass() == listThree.getClass());
System.out.printf("listThree.getClass() == listTwo.getClass() is %b \n",
listThree.getClass() == listTwo.getClass());
System.out.printf("listOne.getClass() is %s \n",listOne.getClass());
System.out.printf("listTwo.getClass() is %s \n",listTwo.getClass());
System.out.printf("listThree.getClass() is %s \n",listThree.getClass());
}
}
它在控制台中的输出如下:
listOne.getClass() == listTwo.getClass() is false
listOne.getClass() == listThree.getClass() is false
listThree.getClass() == listTwo.getClass() is false
listOne.getClass() is class java.util.ArrayList
listTwo.getClass() is class Test$1
listThree.getClass() is class Test$2
答案 0 :(得分:3)
在此创建类ArrayList的新实例
List<String> listOne = new ArrayList<String>();
在这里,您可以定义一个从ArrayList扩展并创建它的新实例的匿名类
List<String> listTwo = new ArrayList<String>(){};
在这里,您定义了另一个匿名类,它从ArrayList扩展并在初始化块中声明并创建它的实例
List<String> listThree = new ArrayList<String>() {{}};
答案 1 :(得分:2)
符号new ArrayList<String>(){};
实例化扩展ArrayList
的匿名类的对象。
这就是为什么第二个和第三个变量的class
是Test$1
和Test$2
(这就是JVM如何命名匿名类)
答案 2 :(得分:1)
List<String> listTwo = new ArrayList<String>(){};
这会创建一个扩展ArrayList<String>
的{{3}}。如果你做listTwo instanceof ArrayList
,你会发现它实际上是ArrayList
(嗯,是一个的子类)。这就像你做了以下课程:
private class SomeClass extends ArrayList<String>
{
}
List<String> listThree = new ArrayList<String>() {{}};
这会像以前一样创建一个匿名类,但是anonymous class(恰好是空的)。这就像你创建了这个类:
private class SomeClass2 extends ArrayList<String>
{
{
// some code could go here...
}
}
这可以initialization block方式使用,例如
List<String> listThree = new ArrayList<String>()
{{
add("hello");
}};
正如您所料,这会创建一个新列表并向其添加“hello”。由于“令人困惑”的一部分,我建议不要这样做。
在您的示例中,所有类的功能都相同,因此您应该使用:
List<String> listOne = new ArrayList<String>();
答案 3 :(得分:0)
list1
是ArrayList
。 list2
是ArrayList
的匿名子类。 list3
是一个带有初始化块的匿名子类。这意味着涉及三个类,其中2个是匿名的,称为Test$1
和Test$2
。 1和2指的是声明它们的顺序,Test
指的是封闭的类。
答案 4 :(得分:0)
后两者是ArrayList
的匿名子类。在大括号内,您可以覆盖通常原始类的行为,因为您可以使用普通继承。
例如:
List<String> listTwo = new ArrayList<String>(){
this.add("hello user!"); //list is automatically initialized with one element
@Override
public int size() {
return super.size() + 1; //this naughty list lies about its size!
}
};
第三个实际上与第二个相同,它在匿名类中只有一个空代码块。