What is Double Brace initialization in Java?

前端 未结 13 2306
旧时难觅i
旧时难觅i 2020-11-21 07:22

What is Double Brace initialization syntax ({{ ... }}) in Java?

13条回答
  •  Happy的楠姐
    2020-11-21 08:01

    Every time someone uses double brace initialisation, a kitten gets killed.

    Apart from the syntax being rather unusual and not really idiomatic (taste is debatable, of course), you are unnecessarily creating two significant problems in your application, which I've just recently blogged about in more detail here.

    1. You're creating way too many anonymous classes

    Each time you use double brace initialisation a new class is made. E.g. this example:

    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");
            }});
        }});
    }};
    

    ... will produce these classes:

    Test$1$1$1.class
    Test$1$1$2.class
    Test$1$1.class
    Test$1.class
    Test.class
    

    That's quite a bit of overhead for your classloader - for nothing! Of course it won't take much initialisation time if you do it once. But if you do this 20'000 times throughout your enterprise application... all that heap memory just for a bit of "syntax sugar"?

    2. You're potentially creating a memory leak!

    If you take the above code and return that map from a method, callers of that method might be unsuspectingly holding on to very heavy resources that cannot be garbage collected. Consider the following example:

    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;
        }
    }
    

    The returned Map will now contain a reference to the enclosing instance of ReallyHeavyObject. You probably don't want to risk that:

    Memory Leak Right Here

    Image from http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/

    3. You can pretend that Java has map literals

    To answer your actual question, people have been using this syntax to pretend that Java has something like map literals, similar to the existing array literals:

    String[] array = { "John", "Doe" };
    Map map = new HashMap() {{ put("John", "Doe"); }};
    

    Some people may find this syntactically stimulating.

提交回复
热议问题