· - Double brace
initializer is nothing but it is instance initializer inside a inner class.
· = Double Brace
Initialization looks convenient for variable initialization for collections
(map,List,set..). This feel good, because we can declare and initialize collections
at the same time.
·
This means we can
declare and initialize at the same time using instance initializer.
E.g we a list and we want to add some elements
to this like "A","B","C". What we will do.
List<String>
list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
Also we
can initialize as below. But this is a unmodifiable list, if we try to modify
this list, it will give java.lang.UnsupportedOperationException
List<String>
listOfLetters1 = Arrays.asList("A", "B",
"C");
Initialize using Double braces:
List<String>
list = new ArrayList<String>()
{
{
add("A");
add("B");
add("C");
}
};
It’s
look pretty and simple, we can do
initialization in one line.
What is Double Brace Initialization?
·
Double brace
initializer is nothing but it is instance initializer inside a inner class.
instance
initializers to instantiate collections
instantiating
and initializing collections without having to manually populate the list.
Declaration
and initialization in one line.
This is not a special
{{ symbol but two { given different meanings. The first { shows this is an
anonymous class, the second { means the start of an initializer block.
How the compiler will consider this? or why it
is saying avoid this ? or why it is calling as anti pattern ?
·
Creating anonymous class while compilation – that decrease the
performance.
Double brace
initializer is just a initializer inside (inner braces) anonymous inner
class(outer braces).
The outer ‘{
‘ represent anonymous
inner class
So every
time when we are creating a map or any collection using double brace
initializer means your creating an anonymous inner class.
At run time
compiler will generate *.class file for each anonymous inner class and that
will loaded and invoked by class loader at runtime.
e.g>
public class
test {
public test
{
List<String>
list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
}
public static void main(String[] args) {
new
test();
}
}
For the
above example after compilation this will be having test.class, test$1.class
i.e for
every anonymous
inner class a ‘.class’ file will be gnereating.
So at
the run time class loader will invoke this, this will reduce overall
performance of your application.
·
Inner classes Keeping a ‘this’ reference to the outer
classes- creating memory leak
For non-static anonymous inner
classes that will always keep reference to their enclosing instance. .i.e the
inner class always have ‘this’ reference (this$0) to the outer class. This will
lead to memory leak- since this is preventing GC from freeing up the occupied
memory.
That is to, serialize the collection you have to
serialize the entire enclosing class.
·
Doesn’t support empty diamond operator (<>)
From Java 7 onwards, we will be to declare variables
using <>,
List<String>
list = new ArrayList< >();
But double brace intializrer is not supporting this.
List<String>
list = new ArrayList< >()
{
{
add("A");
add("B");
add("C");
}
};
The above code will throw compilation error.
Because of the above all disadvantages, we are not using double brace
initializer nowadays, so this become an antipattern.
Where to use: Used only for testing, demos and debugging.
In Java 8 we have Stream API and Collectors available for
initialization of collections.
List<String> list =
Collections.unmodifiableList(Stream.of(("A", "B",
"C").collect(toList()));
But the streams
collectors make no guarantees about the mutability of collections they return
No comments:
Post a Comment