[ACCEPTED]-Anonymous code blocks in Java-java
They restrict variable scope.
public void foo()
{
{
int i = 10;
}
System.out.println(i); // Won't compile.
}
In practice, though, if 3 you find yourself using such a code block 2 that's probably a sign that you want to 1 refactor that block out to a method.
@David Seiler's answer is right, but I would 19 contend that code blocks are very useful 18 and should be used frequently and don't 17 necessarily indicate the need to factor 16 out into a method. I find they are particularly 15 useful for constructing Swing Component 14 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 13 the scope of variables as tightly as possible 12 (which is always good, especially when dealing 11 with mutable state and non-final variables), but 10 they also illustrate the component hierarchy 9 much in the way as XML / HTML making the 8 code easier to read, write and maintain.
My 7 issue with factoring out each component 6 instantiation into a method is that
- The method will only be used once yet exposed to a wider audience, even if it is a private instance method.
- 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 5 Swing example, I find that when complexity 4 really does grow beyond manageability it 3 indicates that it's time to factor out a 2 branch of the tree into a new class rather 1 than a bunch of small methods.
It's usually best to make the scope of local variables as small as possible. Anonymous code blocks 13 can help with this.
I find this especially 12 useful with switch
statements. Consider the following 11 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 10 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 9 second version to be cleaner and easier 8 to read. And, it reduces the scope of variables 7 declared within the switch to the case to 6 which they were declared, which in my experience 5 is what you want 99% of the time anyways.
Be 4 warned however, it does not change the behavior 3 for case fall-through - you'll still need 2 to remember to include a break
or return
to prevent 1 it!
I think you and/or the other answers are 28 confusing two distinct syntactic constructs; namely 27 Instance Initializers and Blocks. (And 26 by the way, a "named block" is really a 25 Labeled Statement, where the Statement happens 24 to be a Block.)
An Instance Initializer is 23 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 22 Initializer construct is most commonly used 21 with anonymous classes as per @dfa's example. Another 20 use-case is for doing complicated initialization 19 of 'final' attributes; e.g. see the example 18 above. (However, it is more common to do 17 this using a regular constructor. The pattern 16 above is more commonly used with Static 15 Initializers.)
The other construct is an 14 ordinary block and appears within a code 13 block such as method; e.g.
public void test() {
int i = 1;
{
int j = 2;
...
}
{
int j = 3;
...
}
}
Blocks are most 12 commonly used as part of control statements 11 to group a sequence of statements. But 10 when you use them above, they (just) allow 9 you to restrict the visibility of declarations; e.g. j
in 8 the above.
This usually indicates that you 7 need to refactor your code, but it is not 6 always clear cut. For example, you sometimes 5 see this sort of thing in interpreters coded 4 in Java. The statements in the switch arms 3 could be factored into separate methods, but 2 this may result in a significant performance 1 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;
}
...
};
You may use it as constructor for anonymous 5 inner classes.
Like this:
This way you can 4 initialize your object, since the free block 3 is executed during the object construction.
It 2 is not restricted to anonymous inner classes, it 1 applies to regular classes too.
public class SomeClass {
public List data;{
data = new ArrayList();
data.add(1);
data.add(1);
data.add(1);
}
}
Anonymous blocks are useful for limiting 1 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");
}};
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
}
}
0
You can use a block to initialize a final 8 variable from the parent scope. This a nice 7 way to limit the scope of some variables 6 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 5 general it's preferable to move the block 4 into a method, but this syntax can be nice 3 for one-off cases when multiple variables 2 need to be returned and you don't want to 1 create a wrapper class.
I use the anonymous blocks for all the reasons 9 explained in other answers, which boils 8 down to limiting the scope of variables. I 7 also use them to have proper delimitation 6 of pairs of method belonging together.
Consider 5 the following excerpt:
jg.writeStartObject();
{
jg.writeStringField("fieldName", ((JsonFormFieldDependencyData.FieldLocator) valueOrLocator).getFieldName());
jg.writeStringField("kind", "field");
}
jg.writeEndObject();
Not only you can see 4 at a glance that the methods are properly 3 paired, but doesn't also kind of look like 2 the output too ?
Just be careful to not abuse 1 it and end up in-lining methods ^^
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.