Anonymous code blocks in Java

Are there any practical uses of anonymous code blocks in Java?

public static void main(String[] args) {
    // in
    {
        // out
    }
}

Please note that this is not about named blocks, i.e.

name: { 
     if ( /* something */ ) 
         break name;
}

.

64 java
13.10.2009 21:34:11
Well, I tend to use them in conjunction with if, else, for, while, do, switch and case.
Tom Hawtin - tackline 14.10.2009 00:16:49
Incidentally, so do I. But then again, I decided not to rule out the uses which ( to me ) seemed obvious, like the ones you mentioned.
Robert Munteanu 14.10.2009 06:29:26
8 ОТВЕТОВ
РЕШЕНИЕ

They restrict variable scope.

public void foo()
{
    {
        int i = 10;
    }
    System.out.println(i); // Won't compile.
}

In practice, though, if you find yourself using such a code block that's probably a sign that you want to refactor that block out to a method.

126
13.10.2009 21:36:31
Good answer, and completely agree with the method comment.
Robert Munteanu 13.10.2009 21:50:04
+1: correct answer, and it is a sign of a desperately needed refactor, aka a "code smell" as Martin Fowler puts it :)
aperkins 13.10.2009 21:56:04
The only time you do not want to factor it out into a private method is if that code block needs a lot of context (in the form of other local variables). But that is probably another code smell...
Thilo 6.12.2011 01:34:22
@Eugene yes, named blocks can also be used that way. But they are usually used as targets for break statements; if I saw a named block without a break statement, I'd wonder if I were looking at a bad merge or half-finished refactoring. My advice: use an unnamed block and a comment. For more discussion, see this SO answer.
David Seiler 18.03.2014 18:25:20
I often use those in testing class, so I don't have to worry about using the same variable name over and over. Pretty neat.
MightyPork 18.04.2014 20:38:27

You may use it as constructor for anonymous inner classes.

Like this:

alt text

This way you can initialize your object, since the free block is executed during the object construction.

It is not restricted to anonymous inner classes, it applies to regular classes too.

public class SomeClass {
    public List data;{
        data = new ArrayList();
        data.add(1);
        data.add(1);
        data.add(1);
    }
}
12
30.04.2019 19:05:31
That's actually an instance initialiser, which is a different thing.
Tom Hawtin - tackline 14.10.2009 00:14:10
Different to ... ? Constructors? Oh yes, I mean "as substitute or complement to.." when referring to constructor.
OscarRyz 14.10.2009 15:59:26
different to code blocks inside methods as demonstrated in the sample code of the question.
Joachim Sauer 13.04.2011 16:06:35
Now that's a pretty cool trick, but with auto-formatting it will turn into an ugly mess. Still interesting idea.
MightyPork 18.04.2014 20:39:52

Anonymous blocks are useful for limiting the scope of a variable as well as for double brace initialization.

Compare

Set<String> validCodes = new HashSet<String>();
validCodes.add("XZ13s");
validCodes.add("AB21/X");
validCodes.add("YYLEX");
validCodes.add("AR2D");

with

Set<String> validCodes = new HashSet<String>() {{
  add("XZ13s");
  add("AB21/X");
  add("YYLEX");
  add("AR5E");
}};
7
29.05.2018 11:26:28
Whoah, that double brace initialization stuff is pretty sweet.
StriplingWarrior 13.10.2009 22:12:21
Bevare though that in a second instance validCodes now is not a HashSet, but rather a subclass of a HashSet. With more complex classes this can lead to some unexpected behavior.
Alexander Pogrebnyak 13.10.2009 22:42:22
Again, instance initialisers are different from blocks.
Tom Hawtin - tackline 14.10.2009 00:14:50
I know the double brace initialization trick, but it's not sweet, it's a dirty trick that will thouroughly confuse people who don't know it. Don't use it!
Jesper 14.10.2009 08:17:18

I think you and/or the other answers are confusing two distinct syntactic constructs; namely Instance Initializers and Blocks. (And by the way, a "named block" is really a Labeled Statement, where the Statement happens to be a Block.)

An Instance Initializer is used at the syntactic level of a class member; e.g.

public class Test {
    final int foo;

    {
         // Some complicated initialization sequence; e.g.
         int tmp;
         if (...) {
             ...
             tmp = ...
         } else {
             ...
             tmp = ...
         }
         foo = tmp;
    }
}

The Initializer construct is most commonly used with anonymous classes as per @dfa's example. Another use-case is for doing complicated initialization of 'final' attributes; e.g. see the example above. (However, it is more common to do this using a regular constructor. The pattern above is more commonly used with Static Initializers.)

The other construct is an ordinary block and appears within a code block such as method; e.g.

public void test() {
    int i = 1;
    {
       int j = 2;
       ...
    }
    {
       int j = 3;
       ...
    }
}

Blocks are most commonly used as part of control statements to group a sequence of statements. But when you use them above, they (just) allow you to restrict the visibility of declarations; e.g. j in the above.

This usually indicates that you need to refactor your code, but it is not always clear cut. For example, you sometimes see this sort of thing in interpreters coded in Java. The statements in the switch arms could be factored into separate methods, but this may result in a significant performance hit for the "inner loop" of an interpreter; e.g.

    switch (op) {
    case OP1: {
             int tmp = ...;
             // do something
             break;
         }
    case OP2: {
             int tmp = ...;
             // do something else
             break;
         }
    ...
    };
17
3.01.2016 00:33:33
Thanks! Could you please expand more or point to some article on the "performance hit for the inner loop of the interpreter" part?
asgs 2.01.2016 23:31:43
Calling a method (that cannot be inlined) takes extra CPU cycles - it is a performance hit. It might be significant
Stephen C 3.01.2016 00:31:29

@David Seiler's answer is right, but I would contend that code blocks are very useful and should be used frequently and don't necessarily indicate the need to factor out into a method. I find they are particularly useful for constructing Swing Component trees, e.g:

JPanel mainPanel = new JPanel(new BorderLayout());
{
    JLabel centerLabel = new JLabel();
    centerLabel.setText("Hello World");
    mainPanel.add(centerLabel, BorderLayout.CENTER);
}
{
    JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0,0));
    {
        JLabel label1 = new JLabel();
        label1.setText("Hello");
        southPanel.add(label1);
    }
    {
        JLabel label2 = new JLabel();
        label2.setText("World");
        southPanel.add(label2);
    }
    mainPanel.add(southPanel, BorderLayout.SOUTH);
}

Not only do the code blocks limit the scope of variables as tightly as possible (which is always good, especially when dealing with mutable state and non-final variables), but they also illustrate the component hierarchy much in the way as XML / HTML making the code easier to read, write and maintain.

My issue with factoring out each component instantiation into a method is that

  1. The method will only be used once yet exposed to a wider audience, even if it is a private instance method.
  2. It's harder to read, imagining a deeper more complex component tree, you'd have to drill down to find the code you're interested, and then loose visual context.

In this Swing example, I find that when complexity really does grow beyond manageability it indicates that it's time to factor out a branch of the tree into a new class rather than a bunch of small methods.

43
13.04.2011 15:49:34
I'm just working through code that uses this "feature" a lot and it's rather difficult to follow. I think it's a bad way to structure code
Jan 3.09.2012 10:51:40
@Jan - there's lots of ways to use good features poorly, and I can imagine this one getting out of hand easily enough (deep nesting, long scrolling, lots of mutation, ...).
Stephen Swensen 3.09.2012 12:42:16
@Jan "Rather difficult to follow" and "incomprehensible clutter" are subjective opinions. All they sum up to is "I am not used to doing it this way, therefore it must be bad." Stephen explained objective reasons why this is better. (And I happen to agree.) So, either come up with objective objections, or remain silent.
Mike Nakis 10.02.2014 15:37:11
It seems to me this this style of coding comes in handy with code that is already incomprehensibly cluttered and difficult to follow. It only makes it slightly easier to follow. I think it's preferable for a class to contain 50 anonymous code blacks rather than 50 small, single-use functions. I'd like to hear dissenting opinions, if there are any.
jonS90 29.01.2015 17:38:59
I'd prefer: mainPanel.add(label("Hello World",...);, and southPanel.add(label("Hello"));, and southPanel.add(label("World")); without the extraneous braces. I cannot fathom how it's harder to read because appropriately named methods should provide clues as to their intent. Also, IDEs show Javadocs as tooltips by hovering over the methods, which implies that visual context is not lost. And refactoring often reduces the possibility of (or draws attention to) copy/paste errors.
Dave Jarvis 29.10.2016 03:57:30

It's usually best to make the scope of local variables as small as possible. Anonymous code blocks can help with this.

I find this especially useful with switch statements. Consider the following example, without anonymous code blocks:

public String manipulate(Mode mode) {
    switch(mode) {
    case FOO: 
        String result = foo();
        tweak(result);
        return result;
    case BAR: 
        String result = bar();  // Compiler error
        twiddle(result);
        return result;
    case BAZ: 
        String rsult = bar();   // Whoops, typo!
        twang(result);  // No compiler error
        return result;
    }
}

And with anonymous code blocks:

public String manipulate(Mode mode) {
    switch(mode) {
        case FOO: {
            String result = foo();
            tweak(result);
            return result;
        }
        case BAR: {
            String result = bar();  // No compiler error
            twiddle(result);
            return result;
        }
        case BAZ: {
            String rsult = bar();   // Whoops, typo!
            twang(result);  // Compiler error
            return result;
        }
    }
}

I consider the second version to be cleaner and easier to read. And, it reduces the scope of variables declared within the switch to the case to which they were declared, which in my experience is what you want 99% of the time anyways.

Be warned however, it does not change the behavior for case fall-through - you'll still need to remember to include a break or return to prevent it!

23
23.05.2017 12:18:14

You can use a block to initialize a final variable from the parent scope. This a nice way to limit the scope of some variables only used to initialize the single variable.

public void test(final int x) {
    final ClassA a;
    final ClassB b;
    {
        final ClassC parmC = getC(x);
        a = parmC.getA();
        b = parmC.getB();
    }
    //... a and b are initialized
}

In general it's preferable to move the block into a method, but this syntax can be nice for one-off cases when multiple variables need to be returned and you don't want to create a wrapper class.

0
27.03.2017 19:28:44
I don't see any reason to use the curly brackets block in this case, it is useless.
Sam 24.06.2018 10:16:31

Instance initializer block:

class Test {
    // this line of code is executed whenever a new instance of Test is created
    { System.out.println("Instance created!"); }

    public static void main() {
        new Test(); // prints "Instance created!"
        new Test(); // prints "Instance created!"
    }
}

Anonymous initializer block:

class Test {

    class Main {
        public void method() {
            System.out.println("Test method");
        }
    }

    public static void main(String[] args) {
        new Test().new Main() {
            {
                method(); // prints "Test method"
            }
        };

        {
            //=========================================================================
            // which means you can even create a List using double brace
            List<String> list = new ArrayList<>() {
                {
                    add("el1");
                    add("el2");
                }
            };
            System.out.println(list); // prints [el1, el2]
        }

        {
            //==========================================================================
            // you can even create your own methods for your anonymous class and use them
            List<String> list = new ArrayList<String>() {
                private void myCustomMethod(String s1, String s2) {
                    add(s1);
                    add(s2);
                }

                {
                    myCustomMethod("el3", "el4");
                }
            };

            System.out.println(list); // prints [el3, el4]
        }
    }
}

Variable scope restrict:

class Test {
    public static void main() {
        { int i = 20; }
        System.out.println(i); // error
    }
}
2
30.01.2018 16:09:16