什么是双大括号初始化语法({{…}})在Java?


当前回答

你是说像这样的事?

List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};

这是在创建时初始化数组列表(hack)

其他回答

你可以把一些Java语句作为循环来初始化集合:

List<Character> characters = new ArrayList<Character>() {
    {
        for (char c = 'A'; c <= 'E'; c++) add(c);
    }
};

Random rnd = new Random();

List<Integer> integers = new ArrayList<Integer>() {
    {
         while (size() < 10) add(rnd.nextInt(1_000_000));
    }
};

但这种情况对性能有影响,请检查此讨论

关于双大括号初始化的有趣应用,请参阅这里的Dwemthy 's Array in Java。

摘录

private static class IndustrialRaverMonkey
  extends Creature.Base {{
    life = 46;
    strength = 35;
    charisma = 91;
    weapon = 2;
  }}

private static class DwarvenAngel
  extends Creature.Base {{
    life = 540;
    strength = 6;
    charisma = 144;
    weapon = 50;
  }}

现在,准备好迎接香肠味和培根味的大战吧!

第一个大括号创建了一个新的匿名内部类。 第二组大括号创建了一个实例初始化器,类似于Class中的static block。

例如:

   public class TestHashMap {
    public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<String,String>(){
        {
            put("1", "ONE");
        }{
            put("2", "TWO");
        }{
            put("3", "THREE");
        }
        };
        Set<String> keySet = map.keySet();
        for (String string : keySet) {
            System.out.println(string+" ->"+map.get(string));
        }
    }
    
}

它是如何工作的

第一个大括号创建了一个新的匿名内部类。这些内部类能够访问它们的父类的行为。因此,在本例中,我们实际上是在创建HashSet类的子类,因此这个内部类能够使用put()方法。

第二组大括号只是实例初始化器。如果你还记得核心java概念,那么你可以很容易地将实例初始化器块与静态初始化器关联起来,因为类似struct的大括号。唯一的区别是静态初始化器添加了static关键字,并且只运行一次;不管你创建了多少个对象。

more

在其他用途中,它是初始化集合的快捷方式。了解更多…

为了避免双大括号初始化的所有负面影响,例如:

打破了“平等”的兼容性。 使用直接赋值时不执行检查。 可能存在内存泄漏。

做下面的事情:

创建单独的“Builder”类,专门用于双大括号初始化。 用默认值声明字段。 将对象创建方法放在该类中。

例子:

public class MyClass {
    public static class Builder {
        public int    first  = -1        ;
        public double second = Double.NaN;
        public String third  = null      ;

        public MyClass create() {
            return new MyClass(first, second, third);
        }
    }

    protected final int    first ;
    protected final double second;
    protected final String third ;

    protected MyClass(
        int    first ,
        double second,
        String third
    ) {
        this.first = first ;
        this.second= second;
        this.third = third ;
    }

    public int    first () { return first ; }
    public double second() { return second; }
    public String third () { return third ; }
}

用法:

MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();

优点:

简单易用。 不要破坏“对等”的兼容性。 您可以在创建方法中执行检查。 无内存泄漏。

缺点:

一个也没有。

因此,我们有了有史以来最简单的java构建器模式。

查看github: java-sf-builder-simple-example中的所有示例