How should I interpret this statement about Initializer in Java? [duplicate] - java

What is Double Brace initialization syntax ({{ ... }}) in Java?

Double brace initialisation creates an anonymous class derived from the specified class (the outer braces), and provides an initialiser block within that class (the inner braces). e.g.
new ArrayList<Integer>() {{
add(1);
add(2);
}};
Note that an effect of using this double brace initialisation is that you're creating anonymous inner classes. The created class has an implicit this pointer to the surrounding outer class. Whilst not normally a problem, it can cause grief in some circumstances e.g. when serialising or garbage collecting, and it's worth being aware of this.

Every time someone uses double brace initialisation, a kitten gets killed.
Apart from the syntax being rather unusual and not really idiomatic (taste is debatable, of course), you are unnecessarily creating two significant problems in your application, which I've just recently blogged about in more detail here.
1. You're creating way too many anonymous classes
Each time you use double brace initialisation a new class is made. E.g. this example:
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
... will produce these classes:
Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class
That's quite a bit of overhead for your classloader - for nothing! Of course it won't take much initialisation time if you do it once. But if you do this 20'000 times throughout your enterprise application... all that heap memory just for a bit of "syntax sugar"?
2. You're potentially creating a memory leak!
If you take the above code and return that map from a method, callers of that method might be unsuspectingly holding on to very heavy resources that cannot be garbage collected. Consider the following example:
public class ReallyHeavyObject {
// Just to illustrate...
private int[] tonsOfValues;
private Resource[] tonsOfResources;
// This method almost does nothing
public Map quickHarmlessMethod() {
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
return source;
}
}
The returned Map will now contain a reference to the enclosing instance of ReallyHeavyObject. You probably don't want to risk that:
Image from http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/
3. You can pretend that Java has map literals
To answer your actual question, people have been using this syntax to pretend that Java has something like map literals, similar to the existing array literals:
String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};
Some people may find this syntactically stimulating.

The first brace creates a new Anonymous Inner Class.
The second set of brace creates an instance initializers like static block in Class.
For example:
public class TestHashMap {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>(){
{
put("1", "ONE");
}{
put("2", "TWO");
}{
put("3", "THREE");
}
};
Set<String> keySet = map.keySet();
for (String string : keySet) {
System.out.println(string+" ->"+map.get(string));
}
}
}
How it works
First brace creates a new Anonymous Inner Class. These inner classes are capable of accessing the behavior of their parent class. So, in our case, we are actually creating a subclass of HashSet class, so this inner class is capable of using put() method.
And Second set of braces are nothing but instance initializers. If you remember core java concepts then you can easily associate instance initializer blocks with static initializers due to similar brace like struct. Only difference is that static initializer is added with static keyword, and is run only once; no matter how many objects you create.
more

For a fun application of double brace initialization, see here Dwemthy’s Array in Java.
An excerpt
private static class IndustrialRaverMonkey
extends Creature.Base {{
life = 46;
strength = 35;
charisma = 91;
weapon = 2;
}}
private static class DwarvenAngel
extends Creature.Base {{
life = 540;
strength = 6;
charisma = 144;
weapon = 50;
}}
And now, be prepared for the BattleOfGrottoOfSausageSmells and … chunky bacon!

I think it's important to stress that there is no such thing as "Double Brace initialization" in Java. Oracle web-site doesn't have this term. In this example there are two features used together: anonymous class and initializer block. Seems like the old initializer block has been forgotten by developers and cause some confusion in this topic. Citation from Oracle docs:
Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}

1- There is no such thing as double braces:
I'd like to point out that there is no such thing as double brace initialization. There is only normal traditional one brace initializaition block. Second braces block has nothing to do with initialization. Answers say that those two braces initialize something, but it is not like that.
2- It's not just about anonymous classes but all classes:
Almost all answers talk that it is a thing used when creating anonymous inner classes. I think that people reading those answers will get the impression that this is only used when creating anonymous inner classes. But it is used in all classes. Reading those answers it looks like is some brand new special feature dedicated to anonymous classes and I think that is misleading.
3- The purpose is just about placing brackets after each other, not new concept:
Going further, this question talks about situation when second opening bracket is just after first opening bracket. When used in normal class usually there is some code between two braces, but it is totally the same thing. So it is a matter of placing brackets. So I think we should not say that this is some new exciting thing, because this is the thing which we all know, but just written with some code between brackets. We should not create new concept called "double brace initialization".
4- Creating nested anonymous classes has nothing to do with two braces:
I don't agree with an argument that you create too many anonymous classes. You're not creating them because an initialization block, but just because you create them. They would be created even if you did not use two braces initialization so those problems would occur even without initialization... Initialization is not the factor which creates initialized objects.
Additionally we should not talk about problem created by using this non-existent thing "double brace initialization" or even by normal one bracket initialization, because described problems exist only because of creating anonymous class so it has nothing to do with original question. But all answers with give the readers impression that it is not fault of creating anonymous classes, but this evil (non-existent) thing called "double brace initialization".

To avoid all negative effects of double brace initialization, such as:
Broken "equals" compatibility.
No checks performed, when use direct assignments.
Possible memory leaks.
do next things:
Make separate "Builder" class especially for double brace initialization.
Declare fields with default values.
Put object creation method in that class.
Example:
public class MyClass {
public static class Builder {
public int first = -1 ;
public double second = Double.NaN;
public String third = null ;
public MyClass create() {
return new MyClass(first, second, third);
}
}
protected final int first ;
protected final double second;
protected final String third ;
protected MyClass(
int first ,
double second,
String third
) {
this.first = first ;
this.second= second;
this.third = third ;
}
public int first () { return first ; }
public double second() { return second; }
public String third () { return third ; }
}
Usage:
MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();
Advantages:
Simply to use.
Do not breaks "equals" compatibility.
You can perform checks in creation method.
No memory leaks.
Disadvantages:
None.
And, as a result, we have simplest java builder pattern ever.
See all samples at github: java-sf-builder-simple-example

As pointed out by #Lukas Eder double braces initialization of collections must be avoided.
It creates an anonymous inner class, and since all internal classes keep a reference to the parent instance it can - and 99% likely will - prevent garbage collection if these collection objects are referenced by more objects than just the declaring one.
Java 9 has introduced convenience methods List.of, Set.of, and Map.of, which should be used instead. They're faster and more efficient than the double-brace initializer.

It's - among other uses - a shortcut for initializing collections. Learn more ...

you mean something like this?
List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};
it's an array list initialization in creation time (hack)

You can put some Java statements as loop to initialize collection:
List<Character> characters = new ArrayList<Character>() {
{
for (char c = 'A'; c <= 'E'; c++) add(c);
}
};
Random rnd = new Random();
List<Integer> integers = new ArrayList<Integer>() {
{
while (size() < 10) add(rnd.nextInt(1_000_000));
}
};
But this case affect to performance, check this discussion

The first brace creates a new Anonymous Class and the second set of brace creates an instance initializers like the static block.
Like others have pointed, it's not safe to use.
However, you can always use this alternative for initializing collections.
Java 8
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Java 9
List<String> list = List.of("A", "B", "C");

This would appear to be the same as the with keyword so popular in flash and vbscript. It's a method of changing what this is and nothing more.

Related

The getClass() method returns other class [duplicate]

What is Double Brace initialization syntax ({{ ... }}) in Java?
Double brace initialisation creates an anonymous class derived from the specified class (the outer braces), and provides an initialiser block within that class (the inner braces). e.g.
new ArrayList<Integer>() {{
add(1);
add(2);
}};
Note that an effect of using this double brace initialisation is that you're creating anonymous inner classes. The created class has an implicit this pointer to the surrounding outer class. Whilst not normally a problem, it can cause grief in some circumstances e.g. when serialising or garbage collecting, and it's worth being aware of this.
Every time someone uses double brace initialisation, a kitten gets killed.
Apart from the syntax being rather unusual and not really idiomatic (taste is debatable, of course), you are unnecessarily creating two significant problems in your application, which I've just recently blogged about in more detail here.
1. You're creating way too many anonymous classes
Each time you use double brace initialisation a new class is made. E.g. this example:
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
... will produce these classes:
Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class
That's quite a bit of overhead for your classloader - for nothing! Of course it won't take much initialisation time if you do it once. But if you do this 20'000 times throughout your enterprise application... all that heap memory just for a bit of "syntax sugar"?
2. You're potentially creating a memory leak!
If you take the above code and return that map from a method, callers of that method might be unsuspectingly holding on to very heavy resources that cannot be garbage collected. Consider the following example:
public class ReallyHeavyObject {
// Just to illustrate...
private int[] tonsOfValues;
private Resource[] tonsOfResources;
// This method almost does nothing
public Map quickHarmlessMethod() {
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
return source;
}
}
The returned Map will now contain a reference to the enclosing instance of ReallyHeavyObject. You probably don't want to risk that:
Image from http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/
3. You can pretend that Java has map literals
To answer your actual question, people have been using this syntax to pretend that Java has something like map literals, similar to the existing array literals:
String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};
Some people may find this syntactically stimulating.
The first brace creates a new Anonymous Inner Class.
The second set of brace creates an instance initializers like static block in Class.
For example:
public class TestHashMap {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>(){
{
put("1", "ONE");
}{
put("2", "TWO");
}{
put("3", "THREE");
}
};
Set<String> keySet = map.keySet();
for (String string : keySet) {
System.out.println(string+" ->"+map.get(string));
}
}
}
How it works
First brace creates a new Anonymous Inner Class. These inner classes are capable of accessing the behavior of their parent class. So, in our case, we are actually creating a subclass of HashSet class, so this inner class is capable of using put() method.
And Second set of braces are nothing but instance initializers. If you remember core java concepts then you can easily associate instance initializer blocks with static initializers due to similar brace like struct. Only difference is that static initializer is added with static keyword, and is run only once; no matter how many objects you create.
more
For a fun application of double brace initialization, see here Dwemthy’s Array in Java.
An excerpt
private static class IndustrialRaverMonkey
extends Creature.Base {{
life = 46;
strength = 35;
charisma = 91;
weapon = 2;
}}
private static class DwarvenAngel
extends Creature.Base {{
life = 540;
strength = 6;
charisma = 144;
weapon = 50;
}}
And now, be prepared for the BattleOfGrottoOfSausageSmells and … chunky bacon!
I think it's important to stress that there is no such thing as "Double Brace initialization" in Java. Oracle web-site doesn't have this term. In this example there are two features used together: anonymous class and initializer block. Seems like the old initializer block has been forgotten by developers and cause some confusion in this topic. Citation from Oracle docs:
Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
1- There is no such thing as double braces:
I'd like to point out that there is no such thing as double brace initialization. There is only normal traditional one brace initializaition block. Second braces block has nothing to do with initialization. Answers say that those two braces initialize something, but it is not like that.
2- It's not just about anonymous classes but all classes:
Almost all answers talk that it is a thing used when creating anonymous inner classes. I think that people reading those answers will get the impression that this is only used when creating anonymous inner classes. But it is used in all classes. Reading those answers it looks like is some brand new special feature dedicated to anonymous classes and I think that is misleading.
3- The purpose is just about placing brackets after each other, not new concept:
Going further, this question talks about situation when second opening bracket is just after first opening bracket. When used in normal class usually there is some code between two braces, but it is totally the same thing. So it is a matter of placing brackets. So I think we should not say that this is some new exciting thing, because this is the thing which we all know, but just written with some code between brackets. We should not create new concept called "double brace initialization".
4- Creating nested anonymous classes has nothing to do with two braces:
I don't agree with an argument that you create too many anonymous classes. You're not creating them because an initialization block, but just because you create them. They would be created even if you did not use two braces initialization so those problems would occur even without initialization... Initialization is not the factor which creates initialized objects.
Additionally we should not talk about problem created by using this non-existent thing "double brace initialization" or even by normal one bracket initialization, because described problems exist only because of creating anonymous class so it has nothing to do with original question. But all answers with give the readers impression that it is not fault of creating anonymous classes, but this evil (non-existent) thing called "double brace initialization".
To avoid all negative effects of double brace initialization, such as:
Broken "equals" compatibility.
No checks performed, when use direct assignments.
Possible memory leaks.
do next things:
Make separate "Builder" class especially for double brace initialization.
Declare fields with default values.
Put object creation method in that class.
Example:
public class MyClass {
public static class Builder {
public int first = -1 ;
public double second = Double.NaN;
public String third = null ;
public MyClass create() {
return new MyClass(first, second, third);
}
}
protected final int first ;
protected final double second;
protected final String third ;
protected MyClass(
int first ,
double second,
String third
) {
this.first = first ;
this.second= second;
this.third = third ;
}
public int first () { return first ; }
public double second() { return second; }
public String third () { return third ; }
}
Usage:
MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();
Advantages:
Simply to use.
Do not breaks "equals" compatibility.
You can perform checks in creation method.
No memory leaks.
Disadvantages:
None.
And, as a result, we have simplest java builder pattern ever.
See all samples at github: java-sf-builder-simple-example
As pointed out by #Lukas Eder double braces initialization of collections must be avoided.
It creates an anonymous inner class, and since all internal classes keep a reference to the parent instance it can - and 99% likely will - prevent garbage collection if these collection objects are referenced by more objects than just the declaring one.
Java 9 has introduced convenience methods List.of, Set.of, and Map.of, which should be used instead. They're faster and more efficient than the double-brace initializer.
It's - among other uses - a shortcut for initializing collections. Learn more ...
you mean something like this?
List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};
it's an array list initialization in creation time (hack)
You can put some Java statements as loop to initialize collection:
List<Character> characters = new ArrayList<Character>() {
{
for (char c = 'A'; c <= 'E'; c++) add(c);
}
};
Random rnd = new Random();
List<Integer> integers = new ArrayList<Integer>() {
{
while (size() < 10) add(rnd.nextInt(1_000_000));
}
};
But this case affect to performance, check this discussion
The first brace creates a new Anonymous Class and the second set of brace creates an instance initializers like the static block.
Like others have pointed, it's not safe to use.
However, you can always use this alternative for initializing collections.
Java 8
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Java 9
List<String> list = List.of("A", "B", "C");
This would appear to be the same as the with keyword so popular in flash and vbscript. It's a method of changing what this is and nothing more.

subclassing to simulate collection literal. Pre jdk9, bad style? [duplicate]

What is Double Brace initialization syntax ({{ ... }}) in Java?
Double brace initialisation creates an anonymous class derived from the specified class (the outer braces), and provides an initialiser block within that class (the inner braces). e.g.
new ArrayList<Integer>() {{
add(1);
add(2);
}};
Note that an effect of using this double brace initialisation is that you're creating anonymous inner classes. The created class has an implicit this pointer to the surrounding outer class. Whilst not normally a problem, it can cause grief in some circumstances e.g. when serialising or garbage collecting, and it's worth being aware of this.
Every time someone uses double brace initialisation, a kitten gets killed.
Apart from the syntax being rather unusual and not really idiomatic (taste is debatable, of course), you are unnecessarily creating two significant problems in your application, which I've just recently blogged about in more detail here.
1. You're creating way too many anonymous classes
Each time you use double brace initialisation a new class is made. E.g. this example:
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
... will produce these classes:
Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class
That's quite a bit of overhead for your classloader - for nothing! Of course it won't take much initialisation time if you do it once. But if you do this 20'000 times throughout your enterprise application... all that heap memory just for a bit of "syntax sugar"?
2. You're potentially creating a memory leak!
If you take the above code and return that map from a method, callers of that method might be unsuspectingly holding on to very heavy resources that cannot be garbage collected. Consider the following example:
public class ReallyHeavyObject {
// Just to illustrate...
private int[] tonsOfValues;
private Resource[] tonsOfResources;
// This method almost does nothing
public Map quickHarmlessMethod() {
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
return source;
}
}
The returned Map will now contain a reference to the enclosing instance of ReallyHeavyObject. You probably don't want to risk that:
Image from http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/
3. You can pretend that Java has map literals
To answer your actual question, people have been using this syntax to pretend that Java has something like map literals, similar to the existing array literals:
String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};
Some people may find this syntactically stimulating.
The first brace creates a new Anonymous Inner Class.
The second set of brace creates an instance initializers like static block in Class.
For example:
public class TestHashMap {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>(){
{
put("1", "ONE");
}{
put("2", "TWO");
}{
put("3", "THREE");
}
};
Set<String> keySet = map.keySet();
for (String string : keySet) {
System.out.println(string+" ->"+map.get(string));
}
}
}
How it works
First brace creates a new Anonymous Inner Class. These inner classes are capable of accessing the behavior of their parent class. So, in our case, we are actually creating a subclass of HashSet class, so this inner class is capable of using put() method.
And Second set of braces are nothing but instance initializers. If you remember core java concepts then you can easily associate instance initializer blocks with static initializers due to similar brace like struct. Only difference is that static initializer is added with static keyword, and is run only once; no matter how many objects you create.
more
For a fun application of double brace initialization, see here Dwemthy’s Array in Java.
An excerpt
private static class IndustrialRaverMonkey
extends Creature.Base {{
life = 46;
strength = 35;
charisma = 91;
weapon = 2;
}}
private static class DwarvenAngel
extends Creature.Base {{
life = 540;
strength = 6;
charisma = 144;
weapon = 50;
}}
And now, be prepared for the BattleOfGrottoOfSausageSmells and … chunky bacon!
I think it's important to stress that there is no such thing as "Double Brace initialization" in Java. Oracle web-site doesn't have this term. In this example there are two features used together: anonymous class and initializer block. Seems like the old initializer block has been forgotten by developers and cause some confusion in this topic. Citation from Oracle docs:
Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
1- There is no such thing as double braces:
I'd like to point out that there is no such thing as double brace initialization. There is only normal traditional one brace initializaition block. Second braces block has nothing to do with initialization. Answers say that those two braces initialize something, but it is not like that.
2- It's not just about anonymous classes but all classes:
Almost all answers talk that it is a thing used when creating anonymous inner classes. I think that people reading those answers will get the impression that this is only used when creating anonymous inner classes. But it is used in all classes. Reading those answers it looks like is some brand new special feature dedicated to anonymous classes and I think that is misleading.
3- The purpose is just about placing brackets after each other, not new concept:
Going further, this question talks about situation when second opening bracket is just after first opening bracket. When used in normal class usually there is some code between two braces, but it is totally the same thing. So it is a matter of placing brackets. So I think we should not say that this is some new exciting thing, because this is the thing which we all know, but just written with some code between brackets. We should not create new concept called "double brace initialization".
4- Creating nested anonymous classes has nothing to do with two braces:
I don't agree with an argument that you create too many anonymous classes. You're not creating them because an initialization block, but just because you create them. They would be created even if you did not use two braces initialization so those problems would occur even without initialization... Initialization is not the factor which creates initialized objects.
Additionally we should not talk about problem created by using this non-existent thing "double brace initialization" or even by normal one bracket initialization, because described problems exist only because of creating anonymous class so it has nothing to do with original question. But all answers with give the readers impression that it is not fault of creating anonymous classes, but this evil (non-existent) thing called "double brace initialization".
To avoid all negative effects of double brace initialization, such as:
Broken "equals" compatibility.
No checks performed, when use direct assignments.
Possible memory leaks.
do next things:
Make separate "Builder" class especially for double brace initialization.
Declare fields with default values.
Put object creation method in that class.
Example:
public class MyClass {
public static class Builder {
public int first = -1 ;
public double second = Double.NaN;
public String third = null ;
public MyClass create() {
return new MyClass(first, second, third);
}
}
protected final int first ;
protected final double second;
protected final String third ;
protected MyClass(
int first ,
double second,
String third
) {
this.first = first ;
this.second= second;
this.third = third ;
}
public int first () { return first ; }
public double second() { return second; }
public String third () { return third ; }
}
Usage:
MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();
Advantages:
Simply to use.
Do not breaks "equals" compatibility.
You can perform checks in creation method.
No memory leaks.
Disadvantages:
None.
And, as a result, we have simplest java builder pattern ever.
See all samples at github: java-sf-builder-simple-example
As pointed out by #Lukas Eder double braces initialization of collections must be avoided.
It creates an anonymous inner class, and since all internal classes keep a reference to the parent instance it can - and 99% likely will - prevent garbage collection if these collection objects are referenced by more objects than just the declaring one.
Java 9 has introduced convenience methods List.of, Set.of, and Map.of, which should be used instead. They're faster and more efficient than the double-brace initializer.
It's - among other uses - a shortcut for initializing collections. Learn more ...
you mean something like this?
List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};
it's an array list initialization in creation time (hack)
You can put some Java statements as loop to initialize collection:
List<Character> characters = new ArrayList<Character>() {
{
for (char c = 'A'; c <= 'E'; c++) add(c);
}
};
Random rnd = new Random();
List<Integer> integers = new ArrayList<Integer>() {
{
while (size() < 10) add(rnd.nextInt(1_000_000));
}
};
But this case affect to performance, check this discussion
The first brace creates a new Anonymous Class and the second set of brace creates an instance initializers like the static block.
Like others have pointed, it's not safe to use.
However, you can always use this alternative for initializing collections.
Java 8
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Java 9
List<String> list = List.of("A", "B", "C");
This would appear to be the same as the with keyword so popular in flash and vbscript. It's a method of changing what this is and nothing more.

The difference between two ways of assigning java objects [duplicate]

What is Double Brace initialization syntax ({{ ... }}) in Java?
Double brace initialisation creates an anonymous class derived from the specified class (the outer braces), and provides an initialiser block within that class (the inner braces). e.g.
new ArrayList<Integer>() {{
add(1);
add(2);
}};
Note that an effect of using this double brace initialisation is that you're creating anonymous inner classes. The created class has an implicit this pointer to the surrounding outer class. Whilst not normally a problem, it can cause grief in some circumstances e.g. when serialising or garbage collecting, and it's worth being aware of this.
Every time someone uses double brace initialisation, a kitten gets killed.
Apart from the syntax being rather unusual and not really idiomatic (taste is debatable, of course), you are unnecessarily creating two significant problems in your application, which I've just recently blogged about in more detail here.
1. You're creating way too many anonymous classes
Each time you use double brace initialisation a new class is made. E.g. this example:
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
... will produce these classes:
Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class
That's quite a bit of overhead for your classloader - for nothing! Of course it won't take much initialisation time if you do it once. But if you do this 20'000 times throughout your enterprise application... all that heap memory just for a bit of "syntax sugar"?
2. You're potentially creating a memory leak!
If you take the above code and return that map from a method, callers of that method might be unsuspectingly holding on to very heavy resources that cannot be garbage collected. Consider the following example:
public class ReallyHeavyObject {
// Just to illustrate...
private int[] tonsOfValues;
private Resource[] tonsOfResources;
// This method almost does nothing
public Map quickHarmlessMethod() {
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
return source;
}
}
The returned Map will now contain a reference to the enclosing instance of ReallyHeavyObject. You probably don't want to risk that:
Image from http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/
3. You can pretend that Java has map literals
To answer your actual question, people have been using this syntax to pretend that Java has something like map literals, similar to the existing array literals:
String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};
Some people may find this syntactically stimulating.
The first brace creates a new Anonymous Inner Class.
The second set of brace creates an instance initializers like static block in Class.
For example:
public class TestHashMap {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>(){
{
put("1", "ONE");
}{
put("2", "TWO");
}{
put("3", "THREE");
}
};
Set<String> keySet = map.keySet();
for (String string : keySet) {
System.out.println(string+" ->"+map.get(string));
}
}
}
How it works
First brace creates a new Anonymous Inner Class. These inner classes are capable of accessing the behavior of their parent class. So, in our case, we are actually creating a subclass of HashSet class, so this inner class is capable of using put() method.
And Second set of braces are nothing but instance initializers. If you remember core java concepts then you can easily associate instance initializer blocks with static initializers due to similar brace like struct. Only difference is that static initializer is added with static keyword, and is run only once; no matter how many objects you create.
more
For a fun application of double brace initialization, see here Dwemthy’s Array in Java.
An excerpt
private static class IndustrialRaverMonkey
extends Creature.Base {{
life = 46;
strength = 35;
charisma = 91;
weapon = 2;
}}
private static class DwarvenAngel
extends Creature.Base {{
life = 540;
strength = 6;
charisma = 144;
weapon = 50;
}}
And now, be prepared for the BattleOfGrottoOfSausageSmells and … chunky bacon!
I think it's important to stress that there is no such thing as "Double Brace initialization" in Java. Oracle web-site doesn't have this term. In this example there are two features used together: anonymous class and initializer block. Seems like the old initializer block has been forgotten by developers and cause some confusion in this topic. Citation from Oracle docs:
Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
1- There is no such thing as double braces:
I'd like to point out that there is no such thing as double brace initialization. There is only normal traditional one brace initializaition block. Second braces block has nothing to do with initialization. Answers say that those two braces initialize something, but it is not like that.
2- It's not just about anonymous classes but all classes:
Almost all answers talk that it is a thing used when creating anonymous inner classes. I think that people reading those answers will get the impression that this is only used when creating anonymous inner classes. But it is used in all classes. Reading those answers it looks like is some brand new special feature dedicated to anonymous classes and I think that is misleading.
3- The purpose is just about placing brackets after each other, not new concept:
Going further, this question talks about situation when second opening bracket is just after first opening bracket. When used in normal class usually there is some code between two braces, but it is totally the same thing. So it is a matter of placing brackets. So I think we should not say that this is some new exciting thing, because this is the thing which we all know, but just written with some code between brackets. We should not create new concept called "double brace initialization".
4- Creating nested anonymous classes has nothing to do with two braces:
I don't agree with an argument that you create too many anonymous classes. You're not creating them because an initialization block, but just because you create them. They would be created even if you did not use two braces initialization so those problems would occur even without initialization... Initialization is not the factor which creates initialized objects.
Additionally we should not talk about problem created by using this non-existent thing "double brace initialization" or even by normal one bracket initialization, because described problems exist only because of creating anonymous class so it has nothing to do with original question. But all answers with give the readers impression that it is not fault of creating anonymous classes, but this evil (non-existent) thing called "double brace initialization".
To avoid all negative effects of double brace initialization, such as:
Broken "equals" compatibility.
No checks performed, when use direct assignments.
Possible memory leaks.
do next things:
Make separate "Builder" class especially for double brace initialization.
Declare fields with default values.
Put object creation method in that class.
Example:
public class MyClass {
public static class Builder {
public int first = -1 ;
public double second = Double.NaN;
public String third = null ;
public MyClass create() {
return new MyClass(first, second, third);
}
}
protected final int first ;
protected final double second;
protected final String third ;
protected MyClass(
int first ,
double second,
String third
) {
this.first = first ;
this.second= second;
this.third = third ;
}
public int first () { return first ; }
public double second() { return second; }
public String third () { return third ; }
}
Usage:
MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();
Advantages:
Simply to use.
Do not breaks "equals" compatibility.
You can perform checks in creation method.
No memory leaks.
Disadvantages:
None.
And, as a result, we have simplest java builder pattern ever.
See all samples at github: java-sf-builder-simple-example
As pointed out by #Lukas Eder double braces initialization of collections must be avoided.
It creates an anonymous inner class, and since all internal classes keep a reference to the parent instance it can - and 99% likely will - prevent garbage collection if these collection objects are referenced by more objects than just the declaring one.
Java 9 has introduced convenience methods List.of, Set.of, and Map.of, which should be used instead. They're faster and more efficient than the double-brace initializer.
It's - among other uses - a shortcut for initializing collections. Learn more ...
you mean something like this?
List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};
it's an array list initialization in creation time (hack)
You can put some Java statements as loop to initialize collection:
List<Character> characters = new ArrayList<Character>() {
{
for (char c = 'A'; c <= 'E'; c++) add(c);
}
};
Random rnd = new Random();
List<Integer> integers = new ArrayList<Integer>() {
{
while (size() < 10) add(rnd.nextInt(1_000_000));
}
};
But this case affect to performance, check this discussion
The first brace creates a new Anonymous Class and the second set of brace creates an instance initializers like the static block.
Like others have pointed, it's not safe to use.
However, you can always use this alternative for initializing collections.
Java 8
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Java 9
List<String> list = List.of("A", "B", "C");
This would appear to be the same as the with keyword so popular in flash and vbscript. It's a method of changing what this is and nothing more.

Java instanciation syntax explanation [duplicate]

What is Double Brace initialization syntax ({{ ... }}) in Java?
Double brace initialisation creates an anonymous class derived from the specified class (the outer braces), and provides an initialiser block within that class (the inner braces). e.g.
new ArrayList<Integer>() {{
add(1);
add(2);
}};
Note that an effect of using this double brace initialisation is that you're creating anonymous inner classes. The created class has an implicit this pointer to the surrounding outer class. Whilst not normally a problem, it can cause grief in some circumstances e.g. when serialising or garbage collecting, and it's worth being aware of this.
Every time someone uses double brace initialisation, a kitten gets killed.
Apart from the syntax being rather unusual and not really idiomatic (taste is debatable, of course), you are unnecessarily creating two significant problems in your application, which I've just recently blogged about in more detail here.
1. You're creating way too many anonymous classes
Each time you use double brace initialisation a new class is made. E.g. this example:
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
... will produce these classes:
Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class
That's quite a bit of overhead for your classloader - for nothing! Of course it won't take much initialisation time if you do it once. But if you do this 20'000 times throughout your enterprise application... all that heap memory just for a bit of "syntax sugar"?
2. You're potentially creating a memory leak!
If you take the above code and return that map from a method, callers of that method might be unsuspectingly holding on to very heavy resources that cannot be garbage collected. Consider the following example:
public class ReallyHeavyObject {
// Just to illustrate...
private int[] tonsOfValues;
private Resource[] tonsOfResources;
// This method almost does nothing
public Map quickHarmlessMethod() {
Map source = new HashMap(){{
put("firstName", "John");
put("lastName", "Smith");
put("organizations", new HashMap(){{
put("0", new HashMap(){{
put("id", "1234");
}});
put("abc", new HashMap(){{
put("id", "5678");
}});
}});
}};
return source;
}
}
The returned Map will now contain a reference to the enclosing instance of ReallyHeavyObject. You probably don't want to risk that:
Image from http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/
3. You can pretend that Java has map literals
To answer your actual question, people have been using this syntax to pretend that Java has something like map literals, similar to the existing array literals:
String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};
Some people may find this syntactically stimulating.
The first brace creates a new Anonymous Inner Class.
The second set of brace creates an instance initializers like static block in Class.
For example:
public class TestHashMap {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>(){
{
put("1", "ONE");
}{
put("2", "TWO");
}{
put("3", "THREE");
}
};
Set<String> keySet = map.keySet();
for (String string : keySet) {
System.out.println(string+" ->"+map.get(string));
}
}
}
How it works
First brace creates a new Anonymous Inner Class. These inner classes are capable of accessing the behavior of their parent class. So, in our case, we are actually creating a subclass of HashSet class, so this inner class is capable of using put() method.
And Second set of braces are nothing but instance initializers. If you remember core java concepts then you can easily associate instance initializer blocks with static initializers due to similar brace like struct. Only difference is that static initializer is added with static keyword, and is run only once; no matter how many objects you create.
more
For a fun application of double brace initialization, see here Dwemthy’s Array in Java.
An excerpt
private static class IndustrialRaverMonkey
extends Creature.Base {{
life = 46;
strength = 35;
charisma = 91;
weapon = 2;
}}
private static class DwarvenAngel
extends Creature.Base {{
life = 540;
strength = 6;
charisma = 144;
weapon = 50;
}}
And now, be prepared for the BattleOfGrottoOfSausageSmells and … chunky bacon!
I think it's important to stress that there is no such thing as "Double Brace initialization" in Java. Oracle web-site doesn't have this term. In this example there are two features used together: anonymous class and initializer block. Seems like the old initializer block has been forgotten by developers and cause some confusion in this topic. Citation from Oracle docs:
Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
1- There is no such thing as double braces:
I'd like to point out that there is no such thing as double brace initialization. There is only normal traditional one brace initializaition block. Second braces block has nothing to do with initialization. Answers say that those two braces initialize something, but it is not like that.
2- It's not just about anonymous classes but all classes:
Almost all answers talk that it is a thing used when creating anonymous inner classes. I think that people reading those answers will get the impression that this is only used when creating anonymous inner classes. But it is used in all classes. Reading those answers it looks like is some brand new special feature dedicated to anonymous classes and I think that is misleading.
3- The purpose is just about placing brackets after each other, not new concept:
Going further, this question talks about situation when second opening bracket is just after first opening bracket. When used in normal class usually there is some code between two braces, but it is totally the same thing. So it is a matter of placing brackets. So I think we should not say that this is some new exciting thing, because this is the thing which we all know, but just written with some code between brackets. We should not create new concept called "double brace initialization".
4- Creating nested anonymous classes has nothing to do with two braces:
I don't agree with an argument that you create too many anonymous classes. You're not creating them because an initialization block, but just because you create them. They would be created even if you did not use two braces initialization so those problems would occur even without initialization... Initialization is not the factor which creates initialized objects.
Additionally we should not talk about problem created by using this non-existent thing "double brace initialization" or even by normal one bracket initialization, because described problems exist only because of creating anonymous class so it has nothing to do with original question. But all answers with give the readers impression that it is not fault of creating anonymous classes, but this evil (non-existent) thing called "double brace initialization".
To avoid all negative effects of double brace initialization, such as:
Broken "equals" compatibility.
No checks performed, when use direct assignments.
Possible memory leaks.
do next things:
Make separate "Builder" class especially for double brace initialization.
Declare fields with default values.
Put object creation method in that class.
Example:
public class MyClass {
public static class Builder {
public int first = -1 ;
public double second = Double.NaN;
public String third = null ;
public MyClass create() {
return new MyClass(first, second, third);
}
}
protected final int first ;
protected final double second;
protected final String third ;
protected MyClass(
int first ,
double second,
String third
) {
this.first = first ;
this.second= second;
this.third = third ;
}
public int first () { return first ; }
public double second() { return second; }
public String third () { return third ; }
}
Usage:
MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();
Advantages:
Simply to use.
Do not breaks "equals" compatibility.
You can perform checks in creation method.
No memory leaks.
Disadvantages:
None.
And, as a result, we have simplest java builder pattern ever.
See all samples at github: java-sf-builder-simple-example
As pointed out by #Lukas Eder double braces initialization of collections must be avoided.
It creates an anonymous inner class, and since all internal classes keep a reference to the parent instance it can - and 99% likely will - prevent garbage collection if these collection objects are referenced by more objects than just the declaring one.
Java 9 has introduced convenience methods List.of, Set.of, and Map.of, which should be used instead. They're faster and more efficient than the double-brace initializer.
It's - among other uses - a shortcut for initializing collections. Learn more ...
you mean something like this?
List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};
it's an array list initialization in creation time (hack)
You can put some Java statements as loop to initialize collection:
List<Character> characters = new ArrayList<Character>() {
{
for (char c = 'A'; c <= 'E'; c++) add(c);
}
};
Random rnd = new Random();
List<Integer> integers = new ArrayList<Integer>() {
{
while (size() < 10) add(rnd.nextInt(1_000_000));
}
};
But this case affect to performance, check this discussion
The first brace creates a new Anonymous Class and the second set of brace creates an instance initializers like the static block.
Like others have pointed, it's not safe to use.
However, you can always use this alternative for initializing collections.
Java 8
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Java 9
List<String> list = List.of("A", "B", "C");
This would appear to be the same as the with keyword so popular in flash and vbscript. It's a method of changing what this is and nothing more.

When is "map = new HashMap<>()" being called?

class Node {
char val;
boolean wordEnd;
Map<Character, Node> map = new HashMap<>();
public Node() {}
public Node(char v) {
val = v;
}
}
In Java, when is map = new HashMap<>() being called?
I see I have 2 constructors here. But when is the "map" line being called? Before or after the constructor?
Also, why can we define map with new like this? In C++, I think it is not right.
I thought we should declare the map first, then in constructor, we new it.
when is map = new HashMap<>() being called?
All initializers are called in the order that they appear in the text of the class. All initializers complete before the constructor's code gets started, so you shouldn't be afraid that your map is still null when you are inside the constructor. See section 12.5 of JLS for details.
Also, why can we define map with new like this? In C++, I think it is not right.
C++ lacks this syntax, except for static initializers in the later versions of the standard. Even though Java and C++ borrow from common sources, they remain very different languages, with rather different philosophies behind them.

Categories

Resources