Efficiency of Java “Double Brace Initialization”?

前端 未结 15 2386
清歌不尽
清歌不尽 2020-11-21 15:35

In Hidden Features of Java the top answer mentions Double Brace Initialization, with a very enticing syntax:

Set flavors = new HashSet         


        
15条回答
  •  野的像风
    2020-11-21 16:08

    One property of this approach that has not been pointed out so far is that because you create inner classes, the whole containing class is captured in its scope. This means that as long as your Set is alive, it will retain a pointer to the containing instance (this$0) and keep that from being garbage-collected, which could be an issue.

    This, and the fact that a new class gets created in the first place even though a regular HashSet would work just fine (or even better), makes me not want to use this construct (even though I really long for the syntactic sugar).

    Second question: The new HashSet must be the "this" used in the instance initializer ... can anyone shed light on the mechanism? I'd have naively expected "this" to refer to the object initializing "flavors".

    This is just how inner classes work. They get their own this, but they also have pointers to the parent instance, so that you can call methods on the containing object as well. In case of a naming conflict, the inner class (in your case HashSet) takes precedence, but you can prefix "this" with a classname to get the outer method as well.

    public class Test {
    
        public void add(Object o) {
        }
    
        public Set makeSet() {
            return new HashSet() {
                {
                  add("hello"); // HashSet
                  Test.this.add("hello"); // outer instance 
                }
            };
        }
    }
    

    To be clear on the anonymous subclass being created, you could define methods in there as well. For example override HashSet.add()

        public Set makeSet() {
            return new HashSet() {
                {
                  add("hello"); // not HashSet anymore ...
                }
    
                @Override
                boolean add(String s){
    
                }
    
            };
        }
    

提交回复
热议问题