每次有人使用双括号初始化,都会杀死一只小猫。
除了语法相当不寻常且不是真正地道(当然,品味值得商榷)之外,您还不必要地在您的应用程序中产生了两个重大问题,which I've just recently blogged about in more detail here。
1。你创建的匿名类太多了
每次使用双括号初始化时,都会创建一个新类。例如。这个例子:
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
... 将产生这些类:
Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class
这对你的类加载器来说是相当多的开销——没有任何意义!当然,如果您执行一次,它不会花费太多初始化时间。但是,如果您在整个企业应用程序中执行此操作 20,000 次...所有这些堆内存只是为了一点“语法糖”?
2。您可能会造成内存泄漏!
如果您采用上述代码并从方法返回该映射,则该方法的调用者可能会毫无防备地持有无法被垃圾收集的非常重的资源。考虑以下示例:
public class ReallyHeavyObject {
// Just to illustrate...
private int[] tonsOfValues;
private Resource[] tonsOfResources;
// This method almost does nothing
public Map quickHarmlessMethod() {
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
return source;
}
}
返回的Map 现在将包含对ReallyHeavyObject 封闭实例的引用。您可能不想冒险:
图片来自http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/
3。你可以假装 Java 有映射字面量
为了回答你的实际问题,人们一直在使用这种语法来假装 Java 有类似映射文字的东西,类似于现有的数组文字:
String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};
有些人可能会觉得这在句法上很刺激。