Organizational Research By

Surprising Reserch Topic

anonymous code blocks in java


anonymous code blocks in java  using -'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;
}


.
    

asked Sep 16, 2015 by pradip.bhoge
0 votes
25 views



Related Hot Questions

6 Answers

0 votes

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.

answered Sep 16, 2015 by dhananjayksharma
0 votes

@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.

answered Sep 16, 2015 by rajeevr642
0 votes

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);
    }
}
answered Sep 16, 2015 by mannar kande
0 votes

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 the interpreter.

    switch (op) {
    case OP1: {
             int tmp = ...;
             // do something
             break;
         }
    case OP2: {
             int tmp = ...;
             // do something else
             break;
         }
    ...
    };
answered Sep 16, 2015 by loknath.ganji
0 votes

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!

answered Sep 16, 2015 by sujata naik
0 votes

anonymous blocks are useful for limiting scope of variable as well as for double brace initialization. Compare:

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

with:

Set validCodes = new HashSet() {{
  add("XZ13s");
  add("AB21/X");
  add("YYLEX");
  add("AR5E");
}});
answered Sep 16, 2015 by android_master

...