2013-01-31 81 views
7

必须知道,我们可以使用双大括号初始化来初始化java中的一个集合。并做了一些搜索,发现它不建议使用它,因为它的性能问题。双大括号初始化 - 优点

private static final Set<String> VALID_CODES = new HashSet<String>() {{ 
    add("XZ13s"); 
    add("AB21/X"); 
    add("YYLEX"); 
    add("AR2D"); 
}}; 

只是想知道,是否有任何积极的方面或双重优势的初始化?

+0

不,只有积极的一面是少代码..但不可读所有其他谁不知道双括号初始化。 – Phani

+2

尽管可以用Java编程的人可读性更强,但在非静态环境中,您将获得对封闭“this”的引用。你也可以选择固定的引用来调用mutators时使用的final字段。这对于大多数Java程序员来说并不明显,并且可能导致模糊的内存问题。 //无论如何,你应该写一些类似'private static final Set VALID_CODES = Collections.unmodifiableSet(new HashSet (Arrays。asList(“XZ13s”,“AB21/X”,“YYLEX”,“AR2D”)));'显然。 –

回答

5

由于其性能问题,不建议使用它。

我没有看到任何性能问题。每当你看到有人说我做了/没有做出某些表现的事情时,你应该期待看到详细的分析,比较这些备选方案解释了如何满足特定的需求性能,而另一些则没有。如果你没有看到所有这些,你可能会认为作者只是在猜测。

编辑:虽然我会承认每个类需要少量的时间来加载,运行的性能是完全一样的。我在这里已经展示https://stackoverflow.com/a/14627268/57695

如果您认为它更简单,更清晰,我会使用双重大括号表示法。

一个缺点是,您正在改变可能会混淆不需要的功能的集合的类型。例如等于。

注意:正如Lukas Eder指出的那样,如果您在非静态环境中执行此操作,则需要小心。匿名子类集合将隐式地引用外部实例,并且如果它的寿命比集合长,那么这将是内存泄漏。 Have you ever thought of the possibility of a memory leak?

+1

问题[Java的效率“双Brace初始化”?](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization)实际上讨论了性能问题,它*是* 比较慢。 –

+2

@AlvinWong这个测试看起来相当糟糕 - 特别是,当我看到一个测试返回“0 ms”时,我的第一个猜测是代码还没有运行(在这种情况下这是完全合法的,因为结果是从来没有用过的)。另外,JVM没有正确预热......我不相信这些结果。 – assylias

+0

以上线程的最佳答案有一些评论质疑性能测量 –

2

没有什么特别的性能问题(除了通过类加载器加载类的成本 - 可以忽略不计)

以上创建一个匿名类,因此它包含了一个隐含的this参照周边情况。这可能会导致序列化框架出现混乱。例如你连续创建了你创建的匿名类,并且你突然发现你也试图序列化包含的实例。

我会强调,匿名类可以在不同的框架和语言中使用很多(斯卡拉 - 我在看着你)。我从来没有听说有人认为Scala由于类加载而导致性能问题。初始启动可能是分数慢,但是记住JVM启动,JIT热身,任何网络接入等

你可能会认为你的应用程序占用空间比较大,因为更多的类。我怀疑(再次)的影响是微不足道的(除非你构造了一个匿名类的整个应用程序!)

+0

究竟我们在哪里有一个匿名类? –

+0

我回复@Peter关于类加载 - 它并不总是可以忽略不计。当然,成本是O(1),因为它仅用于类初始化。 – bestsss

+0

除了序列化之外,以这种方式创建内存泄漏的可能性更为严重...... –