31

Possible Duplicate:
Anonymous code blocks in Java

I just came across the following.

if ( test ) {
    {
        // statements 1
    }
    {
        // statements 2
    }
}

It is the first time I've seen this. How does it work?

Community
  • 1
  • 1
Ricardo Sanchez
  • 4,935
  • 11
  • 56
  • 86

7 Answers7

54

It's is just writing two different blocks of code in order to hide local variables.

From the answer to the question "Anonymous code blocks in Java":

Blocks 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 then it's probably a sign that you want to refactor that block out to a method.

Community
  • 1
  • 1
Sapan Diwakar
  • 10,480
  • 6
  • 33
  • 43
  • 7
    No kidding. This is one of these "neat Java tricks" that show up in an academic setting or on certification tests, but which professional Java developers would probably never use. – Steve Perkins Feb 17 '12 at 14:28
  • 16
    It's actually really useful in a _few_ cases to ensure that adjacent blocks of code are actually independent, to avoid cut-and-paste errors, and to avoid needless changes when re-ordering blocks. – DNA Feb 17 '12 at 14:39
  • Yes very useful for some quick and dirty copy and paste ;] – davidfrancis Feb 17 '12 at 14:45
  • 8
    Sure, there are hacky things you can do with this, but I don't see it fitting into any design patterns you would deliberately start out with when first architecting an app. As Sapan said... if you see this showing up in code, it's a pretty good sign that it's time to refactor and clean up the slop. – Steve Perkins Feb 17 '12 at 14:53
  • I've posted an answer showing where I think it _can_ reasonably be useful and sensible (and not hacky) when, by necessity, you have near-duplicate code, but don't want to refactor into separate methods because you want to see the code in a single place. – DNA Feb 17 '12 at 14:57
  • I like your suggestion with that Swing example, DNA, but still... it would just be a temporary crutch while first putting the class together. You wouldn't leave the isolating braces in there once you're done in any cases, would you? – Steve Perkins Feb 17 '12 at 15:06
  • I think it would depend on whether I anticipated later changes to the GUI - if so, I might leave them in place as 'safety scaffolding' for later... – DNA Feb 17 '12 at 15:10
  • How would the originally-declared JButton (or whatever) be used outside the block? – Steve Perkins Feb 17 '12 at 15:26
  • Good point - it wouldn't, as my example stands! ;-) I have over-simplified. However, we could add a line in each block to add the JButton to a Container, for example. – DNA Feb 17 '12 at 15:30
  • 9
    I like to use those blocks simply to structure the code. Lines that belong together are put in one block. Breaking it into methods is overkill and decreases the readability. In my case its just a matter of taste of readability. – js- Feb 17 '12 at 16:25
  • This would be useful in switch statements where variable declarations fall through, even if you have a break inbetween. – Ryan Amos Feb 17 '12 at 18:35
  • 2
    A case statement in a switch block does not define a variable scope, thus it is almost always necessary to use the blocks, just to be able to define intermediate variables that might have the same name in different case statements. I also use them to do add debug code that should compile only for debug builds. – dashesy Feb 17 '12 at 18:55
  • I do the same thing as @js-, the "blocked" code is stuff that belongs logically together, not necessarily to hide the local variables from each other. When the code groups are only about 4-5 lines, that is IMO too little to split out into its own method, especially since code blocks can be folded in Eclipse. – Izkata Feb 17 '12 at 18:58
  • 7
    Can someone who doesn't like use of this explain why? Just wanting to make the scope of a variable clear and compiler-enforced doesn't argue strongly for breaking the flow out into another method. I'm reading a lot of "blecch" without any reason, AFAICT, other than "it looks funny to me". – Ed Staub Feb 17 '12 at 19:43
21

Two examples of where this can be (slightly) useful - in unit tests, and in GUIs, both of which often involve repetitive code:

It's useful in GUI building, where it is incredibly easy to cut-and-paste lines relating to one component and forget to update them for the new component, leading to hard-to-find bugs, e.g.:

    JButton button1 = new JButton("OK");
    button1.setEnabled(false);
    button1.setAlignmentX(-1);

    JButton button2 = new JButton("Apply");
    button1.setEnabled(false);
    button1.setAlignmentX(-1);

Oops, I just configured button1 twice. If you put each button in its own block, then this mistake is picked up by the compiler. Again, you could create each button in a separate method, but that may make it hard to see what is going on (especially given the lack of keywords parameters in Java):

JButton button_ok = makeButton("OK", false, -1);
JButton button_apply = makeButton("Apply", true, 1);
// what exactly is being set here?

...

// much later:
private static JButton makeButton(String name, boolean enabled,
        int alignment)
{
    JButton button = new JButton(name);
    button.setEnabled(enabled);
    button.setAlignmentX(alignment);
    return button;
}

...and you may end up with numerous methods, each handling different variations of parameters, and each only being used maybe twice.

DNA
  • 42,007
  • 12
  • 107
  • 146
  • 1
    Bugs like this are very annoying. Could see the braces being useful temporarily here. Can also be useful during refactoring and tidying, but probably usually best removed in the final code. Also maybe they have a use if you wish to be really controversial and continue or break inside the block. – davidfrancis Feb 17 '12 at 15:58
  • 3
    It can also be useful if you're generating code and don't want to accidentally declare a variable twice if you include the same node twice in a particular script. Our Test Automation team has run into bugs like that. – Yamikuronue Feb 17 '12 at 16:52
  • Using a builder is probably a better solution for this case - it would give you better readability and would eliminate the class of error you are trying to prevent, – ireddick Feb 19 '12 at 15:01
10

The two blocks are independent. So, whatever variables you may have in the first block won't be accessible in the second block - or anywhere outside the first block. It's called code isolation or scoping.

Kimi
  • 6,239
  • 5
  • 32
  • 49
7

{} introduces a scope and variables declared within the scope exist only for that scope. For example:

if ( test ) {

    int i = 0;


    float i = 0;
}

would fail to compile as i has been declared twice in the same scope.

if ( test ) {
    {
        int i = 0;
    }

    {    
        float i = 0;
    }
}

would compile fine as i has not been declared twice in the same scope.

hmjd
  • 120,187
  • 20
  • 207
  • 252
6

Nothing. They declare blocks of code. Normally you wouldn't use them. The only difference will be if you declare a variable in the first one - it won't be accessible in the 2nd.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
4

The two blocks are executed sequentially. Each block defines a new scope for local variables. So you could have

 int i;

in both blocks.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
4

Those are anonymous blocks. They are used to limit scope. Not only in java, but other languages like C# and C.

jim mcnamara
  • 16,005
  • 2
  • 34
  • 51