private List<String> maleList = new ArrayList<String>() { { add("Machael"); add("Scorfield"); add("Other"); } };
上面这段代码我知道是构建一个ArrayList对象并初始化,但是为什么new ArrayList<String>(){{}};为什么要加两对花括号,匿名内部类有点类似这种结构,但这又不是,查看了ArrayList的构造方法如下:
public ArrayList() { this(10); }
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; }
public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
哪位高手给详解一下,不胜感激!
这类初始化方式成为:Java Double Brace Initialization
-------------------------------------------------------
要理解该初始化方式, 首先需要理解匿名类, 它的基本格式如下:
new SuperType(construction parameters) { // inner class methods and data }
而第二个括号中的内容就是普通类中的初始化块,下面来看一个例子:
class Person { private String name; { System.out.println("初始化块 in class Person"); } public Person() { this.name = null; } public Person(String name) { setName(name); } public void setName(String name) { this.name = name; } public String getName() { return name; } } public class Demo { public static void main(String[] args) { Person p1 = new Person("xiao ming"); System.out.println("直接初始化: " + p1.getName()); System.out.println(); Person p2 = new Person() { // 初始化块 { System.out.println("初始化块 in 匿名类"); setName("xiao ming"); } }; System.out.println("双括号初始化: " + p2.getName()); } }
输出的结果如下:
初始化块 in class Person
直接初始化: xiao ming
初始化块 in class Person
初始化块 in 匿名类
双括号初始化: xiao ming
-------------------------------------------------------
希望对你有所帮助~
非常感谢!
@李己铭:
不客气, 想要进一步了解内部类,可以参考我的文摘:http://www.cnblogs.com/grass-and-moon/p/3737786.html
在上面的代码中,new ArrayList<String>(){{}}
是使用了双括号初始化(Double Brace Initialization)的方式来创建���初始化一个匿名内部类对象。
双括号初始化实际上是创建了一个继承自 ArrayList
类的匿名内部类,并在该匿名内部类中使用实例初始化块来添加初始元素。
第一对花括号定义了匿名内部类,并用两个括号初始化它。第二对花括号定义了一个实例初始化块,其中的代码会在匿名内部类的构造函数执行之前执行。
实际上,这种方式会创建一个 ArrayList
的子类,并且使用实例初始化块来添加元素。这样做的好处是可以在初始化时添加元素,而不需要在构造函数中一个个地调用 add()
方法。
对于上面的代码,可以将它等价地重写为以下形式:
private List<String> maleList = new ArrayList<String>() {
{
add("Machael");
add("Scorfield");
add("Other");
}
};
这个方式在某些场景下比较方便,但也有一些潜在问题。由于创建了一个继承自 ArrayList
的子类,这可能会导致一些不可预料的问题,尤其是在涉及到序列化、equals 和 hashCode 等方面时。因此,使用双括号初始化时需要小心使用。
如果只是简单地初始化一个 ArrayList
对象,并添加初始元素,可以使用以下方式:
private List<String> maleList = Arrays.asList("Machael", "Scorfield", "Other");
这样可以在一行代码中创建并初始化 ArrayList
对象,并添加初始元素。