21

I have come to Java from Visual Basic, and seem to think I have been, in many ways, spoiled :p

Is there a way to instantiate an object and modify it inline? Something like:

JFrame aFrame = new JFrame();   
aFrame.add(new JPanel() {.setSize(100,100) .setLocation(50,50) .setBackground(Color.red) });

I was able to @Override methods, but am looking for something simpler. I have search alot, but if there is a specific term for this kind of inline instantiation, it eludes me.

Thank you for your time!

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
GCon
  • 1,397
  • 3
  • 16
  • 33

2 Answers2

46

Yes but some people consider it hacky.

JFrame aFrame = new JFrame();
aFrame.add(new JPanel() {{
 setSize(100,100);
 setLocation(50,50);
 setBackground(Color.red);
}});

Basically you add another layer of {} (instance initialization block), which is executed when the panel is instantiated. therefore you can put any code in it. (like calling setters).

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
ClickerMonkey
  • 1,881
  • 16
  • 13
  • 1
    What is this technique called? I would like to know more about it. – SJuan76 Jan 06 '12 at 22:09
  • 4
    @SJuan76 it's called "anonymous class with an initializer" – alf Jan 06 '12 at 22:10
  • He is using a instance initialization block within the anonymous class, and calling it's inherited methods like this.setSize... – Bhesh Gurung Jan 06 '12 at 22:11
  • Sir! You are a God! I knew it must exist, but I would never imagine using another pair of braces! As for "Anonymous class with an initializer", never would have even dreamed of it :p Thanks again! – GCon Jan 06 '12 at 22:14
  • 3
    With the caveat that if something is looking for a specific class, they won't get it, as this "trick" creates an anonymous class each time it's used. – Dave Newton Jan 06 '12 at 22:17
  • Does anyone know of a compelling reason to do this instead of creating a local variable for the `JPanel` and calling the various set methods? Seems like this is seldom used syntax which is apt to cause some confusion when someone else reads it...? – Jason Braucht Jan 06 '12 at 22:29
  • That... is probably the most bug-prone piece of code I've ever seen. It will execute before the object is properly initialized. – Kent Jul 19 '14 at 01:06
  • That's not true at all... run the following code: http://pastebin.com/kLT1TweU. Maybe you should consider trying something instead of making assumptions about it. – ClickerMonkey Sep 29 '14 at 12:44
  • That´s the Double Curly Braces Anti Pattern. See https://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/ "Every time you use double brace initialization god kills a kitten" - read the article, there are compelling reasons NOT TO USE THAT PATTERN! – JRA_TLL Nov 30 '18 at 07:34
12

A nice trick is presented in @ClickerMonkey's answer. However, if a class supports method chaining, you can use a similar syntax without the initializer "hack":

new ChainClass().setSize(100,100) .setLocation(50,50) .setBackground(Color.red)

The drawback is that the ChainClass must look similar to this:

public class ChainClass  {
  public ChainClass setSize(int w, int h)  {
     // ...
     return this;
  }

  public ChainClass setLocation(int x, int y)  {
    // ...
    return this;
  }

  // etc.
}

This is, sadly, not the case for most standard Java classes. You can implement it for your classes though.

Karel Petranek
  • 15,005
  • 4
  • 44
  • 68