14

For example:

Object o1 = new ArrayList<String>();
Object o2 = new ArrayList<String>(){};
Object o3 = new ArrayList<String>(){{}};

What's the difference?

I can't google out the 2nd/3rd grammar of Java, any reference?

6

7 Answers 7

25

The first creates an ArrayList

The second creates an anonymous subclass of ArrayList which has a specific generic type of String

The third is the same but it has a initializer block which is empty.

Note: Where ever possible, you should write the simplest and clearest code you can, esp if you are thinking about performance.

2
  • 4
    I think you should add "unless there is a detailed comment explaining that there is some weird special need for an anonymous class to circumvent reflection, the 2nd and 3rd cases are just plain stupid, confusing, and wrong."
    – user949300
    Commented Sep 2, 2013 at 18:23
  • 1
    I'll add that JMock uses the third style for it's mocks to subclass and encode expectations.
    – Sled
    Commented Sep 2, 2013 at 19:33
13
Object o1 = new ArrayList<String>();

Creates an ArrayList.

Object o2 = new ArrayList<String>(){};

Here you are creating an anonymous class that extends ArrayList<String> and don't override anything. So the difference it's that you are subclassing an ArrayList without overrding behaviour, never do this if you don't have a good reason.

Object o3 = new ArrayList<String>(){{}};

You are creating the same as 2 but with an empty initalizer block.

6
  • thanks! got it. maybe the second is useful to avoid "type erasure"?
    – marstone
    Commented Sep 2, 2013 at 18:14
  • 2
    @marstone. No that's not the use. Type erasure cannot be avoided.
    – Rohit Jain
    Commented Sep 2, 2013 at 18:15
  • @RohitJain if not, how could google gson keep the generic parameter type by using "new TypeToken<ArrayList<String>>() {}.getType()"? sorry if this is off the topic.
    – marstone
    Commented Sep 2, 2013 at 18:22
  • 1
    @marstone they use black magic of reflection, it's unrelated to anonymous subclasses, you can find some details here
    – Katona
    Commented Sep 2, 2013 at 18:28
  • @Katona: It is absolutely related to anonymous subclasses; I'm not sure how you can claim otherwise. The subclassing is what allows the type-argument to be available at runtime despite erasure. (Sure, it's only available using the black magic of reflection, but without the subclassing even that much would not be possible.)
    – ruakh
    Commented Sep 2, 2013 at 23:15
2
Object o1 = new ArrayList<String>();

Creating a new ArrayList object and assigning it to o1

Object o2 = new ArrayList<String>(){};

Creating a new instance of an anonymous class that extends ArrayList and assigning it to o2

Object o3 = new ArrayList<String>(){{}};

Creating a new instance of a (different from o2) anonymous class that extends ArrayList that has a no-op instance initializer.

Functionally the anon classes assigned to o2 and o3 are equivalent but technically they will be different classes.

0

You are anonymously instantiating a class. You could override methods in the later case without the need to define a new class in an own file.

0

o3 is still an instance of an anonymous subclass of ArrayList which has an empty instance initialization block (the inner {}).

0
// Instantiate an object of type `ArrayList<String>`
Object o1 = new ArrayList<String>();

// Instantiate an anonymous subclass of `ArrayList<String>`
Object o2 = new ArrayList<String>(){};

// Instantiate an anonymous subclass of `ArrayList<String>` with an empty initializer block
Object o3 = new ArrayList<String>(){{}};
0

Object o2 = new ArrayList<String>(){};
it is annonymous inner class that extends ArrayList class and overrides nothing.
Object o2 = new ArrayList<String>(){{}};
it is also annonymous inner class that extends ArrayList class and overrides nothing but has a empty instance block.

Not the answer you're looking for? Browse other questions tagged or ask your own question.