类似ArrayList声明之间的类型差异

时间:2013-11-21 16:08:28

标签: java list arraylist

我正在尝试使用以下方式创建List实例:

List<String> listOne = new ArrayList<String>();

List<String> listTwo = new ArrayList<String>(){};

List<String> listThree = new ArrayList<String>() {{}};

只有listOne被初始化为java.util.ArrayList,但listTwolistThree不是。

在初始化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 

5 个答案:

答案 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的匿名类的对象。

这就是为什么第二个和第三个变量的classTest$1Test$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)

list1ArrayListlist2ArrayList的匿名子类。 list3是一个带有初始化块的匿名子类。这意味着涉及三个类,其中2个是匿名的,称为Test$1Test$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!
    }
};

第三个实际上与第二个相同,它在匿名类中只有一个空代码块。