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?

broomba
  • 109
  • 7
marstone
  • 686
  • 1
  • 10
  • 23

7 Answers7

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.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 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 Sep 02 '13 at 18:23
  • 1
    I'll add that [JMock](http://www.jmock.org) uses the third style for it's mocks to subclass and encode expectations. – Sled Sep 02 '13 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.

nachokk
  • 14,363
  • 4
  • 24
  • 53
  • thanks! got it. maybe the second is useful to avoid "type erasure"? – marstone Sep 02 '13 at 18:14
  • 2
    @marstone. No that's not the use. Type erasure cannot be avoided. – Rohit Jain Sep 02 '13 at 18:15
  • @RohitJain if not, how could google gson keep the generic parameter type by using "new TypeToken>() {}.getType()"? sorry if this is off the topic. – marstone Sep 02 '13 at 18:22
  • 1
    @marstone they use black magic of reflection, it's unrelated to anonymous subclasses, you can find some details [here](https://code.google.com/p/guava-libraries/wiki/ReflectionExplained) – Katona Sep 02 '13 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 Sep 02 '13 at 23:15
  • @ruakh, ok, let me correct myself, it is related to _subclassing_ but doesn't have to be anonymous, and certainly doesn't prevent type erasure. – Katona Sep 03 '13 at 06:35
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.

Dev
  • 11,919
  • 3
  • 40
  • 53
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.

sorencito
  • 2,517
  • 20
  • 21
0

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

Katona
  • 4,816
  • 23
  • 27
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>(){{}};
nneonneo
  • 171,345
  • 36
  • 312
  • 383
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.

Prabhaker A
  • 8,317
  • 1
  • 18
  • 24