简体   繁体   中英

Difference between {} and {{}} initialization in Java

public class A{
}

A a = new A(){{
    final int x = 1; // IT HAS TO BE FINAL HERE. WHY?
}};

A aa = new A(){
    int x = 1; // THIS NEED NOT BE FINAL. WHY?
    final int y = 1; // STILL FINAL IS ALLOWED HERE. WHY?
    public int getX(){
        return x;
    }
};

Can somebody please answer the questions mentioned inside the snippet?

Thanks

The outer set of {} declares an anonymous subclass

The inner set declares an initialization block within that subclass.

With the following example, it becomes easier to understand what's going on:

List<String> strings = new ArrayList<String>() {{
    add("string");
    add("another string");
}};

You basically say: I want a subclass of List, which calls method add at initialization.

It's similar to:

List<String> strings = new ArrayList<String>();
strings.add("string");
strings.add("another string");
A a = new A(){{
    final int x = 1; // IT HAS TO BE FINAL HERE. WHY?

It needn't.

The difference between the two is that in the first case, you're writing the code used to initialize each object in the double braces. That x is its local variable (doesn't have anything to do with objects of class A ).

In the second case, you're defining the classes body. x would be its member variable. If it were static , its class variable. If final a (basically) constant.

I wonder, why would you want to use the first version of the code (the one with {{}}). The x variable declared inside it's not useful at all, it's local only to the block scope in which it was defined, and being inside an anonymous class, you won't be able to reference it anywhere in the code.

And anyway, the first version of x declaration does not need to be final , it compiles just as fine, with or without final .

The first instance A a = new A(){{... has an initialisation block inside the declaration. Another way of writing it would be like this:

A a = new A()
{
    {
        final int x = 1; // This is inside an initialisation block
    }        
};

Changing the formatting makes it a bit more obvious.

In your first example the inner braces create something called an instance initializer. It's an obscure way to initialize variables and call instance methods when an object is constructed. So the first example creates an anonymous subclass of A and creates a local variable within the scope of the initializer. It doesn't have to be final.

In the second example you're creating an anonymous subclass of A but not creating an instance initializer, the variables you create are instance variables of the anonymous subclass.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM