Generics was added in java as part of JDK 5. It is one of the key area from where questions being asked at senior java developer level and expected to have solid understanding of generics fundamentals and its internal workings. The main agenda of this article to understand internal workings of Generics, click here for detailed discussion of generics fundamental.
Lets understand fundamental of generics with an example, followed by we will see the internal of generics. What is generics in java - Generics provides a way for you to communicate the type of a collection to the compiler, so that compiler will verify whether you have used the collection consistently or not and provide tighter type checks at compile time to support generic programming. In other words, in order to avoid run time failure of java program, generics provides a mechanism which force compiler to check for correctness of type (allowed object for placeholder). Lets see this sample code :
Why we need generics ? - generics gives developer an opportunity to fix java program problems at compile time rather than dragging it to run-time failure, as we know run-time failure is a nightmare.
Now come back to main agenda of this article, to understand the internal working of generics.Generic code had to be compatible with preexisting non-generic code(java 4 and before)., so how does backward compitablity has been maintained with generics introduction. The way Java implements generics while satisfying the constraint(to avoid breaking older code) is through the use of erasure. To implement generics, the Java compiler applies type erasure.
What is this erasure and how does it important for generics ?
Erasure is that entity which understand raw java code(embedded with generics syntax) and convert it into plain ordinary classes, interfaces, and methods at compile time,so that generics incur no run-time overhead.
How erasure makes generics embedded code compatible with older java code ?
1. First, when Java code is compiled, all generic type information is removed (erased) and type parameters is replaced with their bound type, which is Object if no explicit bound is specified.The produced byte-code, therefore, contains only ordinary classes, interfaces, and methods.
2. Insert type casts, if necessary to preserve type safety.
3. Generate bridge methods to preserve polymorphism in extended generic types.
Lets consider the following two scenario to understand how a java class with generics syntax transformed independent of generics.
Case 1: Type parameter is unbounded- Column 1 represents java class with generics syntax embedded and column 2 is compiled version after applying erasure:
Since the type parameter T is unbounded(not super class or subclass specified), the Java compiler replaces all placeholder T with Object(parent of all class).
Case 2: Type parameter is bounded- Column 1 represents java class with generics syntax embedded and column 2 is compiled version after applying erasure:
Here the type parameter T is bounded(String super class specified), the Java compiler replaces all placeholder T with java.lang.String.
Now we will see generics in class hierarchy(involved method overriding) and discuss the importance of Bridge method in it.Consider following example with Node as parent class and MyNode as child class extending parent class Node.
So, now bridge method delegates call to original setData(Integer) and maintains polymorphoism.
This is all about generics internal. Please refer this for understanding restriction in generics.
==========End of article=========
Happy learning
Nikhil
Lets understand fundamental of generics with an example, followed by we will see the internal of generics. What is generics in java - Generics provides a way for you to communicate the type of a collection to the compiler, so that compiler will verify whether you have used the collection consistently or not and provide tighter type checks at compile time to support generic programming. In other words, in order to avoid run time failure of java program, generics provides a mechanism which force compiler to check for correctness of type (allowed object for placeholder). Lets see this sample code :
class GenericsSample<T extends Number> { private T data; private T[] intArray; public GenericsSample(T data){ this.data = data; } // methods for finding sum of all numbers of intArray. }In the above sample code, class name has been appended with <T extends Number> i.e: GenericsSample <T extends Number>. By doing so, we instruct compiler that T is a placeholder and only acceptable values for this placeholder is of type Number(Integer,Float, Double,etc.). Please note, primitives are not allowed in generics, that's why Integer not int.
Why we need generics ? - generics gives developer an opportunity to fix java program problems at compile time rather than dragging it to run-time failure, as we know run-time failure is a nightmare.
Now come back to main agenda of this article, to understand the internal working of generics.Generic code had to be compatible with preexisting non-generic code(java 4 and before)., so how does backward compitablity has been maintained with generics introduction. The way Java implements generics while satisfying the constraint(to avoid breaking older code) is through the use of erasure. To implement generics, the Java compiler applies type erasure.
What is this erasure and how does it important for generics ?
Erasure is that entity which understand raw java code(embedded with generics syntax) and convert it into plain ordinary classes, interfaces, and methods at compile time,so that generics incur no run-time overhead.
How erasure makes generics embedded code compatible with older java code ?
1. First, when Java code is compiled, all generic type information is removed (erased) and type parameters is replaced with their bound type, which is Object if no explicit bound is specified.The produced byte-code, therefore, contains only ordinary classes, interfaces, and methods.
2. Insert type casts, if necessary to preserve type safety.
3. Generate bridge methods to preserve polymorphism in extended generic types.
Lets consider the following two scenario to understand how a java class with generics syntax transformed independent of generics.
Case 1: Type parameter is unbounded- Column 1 represents java class with generics syntax embedded and column 2 is compiled version after applying erasure:
Since the type parameter T is unbounded(not super class or subclass specified), the Java compiler replaces all placeholder T with Object(parent of all class).
Case 2: Type parameter is bounded- Column 1 represents java class with generics syntax embedded and column 2 is compiled version after applying erasure:
Here the type parameter T is bounded(String super class specified), the Java compiler replaces all placeholder T with java.lang.String.
Now we will see generics in class hierarchy(involved method overriding) and discuss the importance of Bridge method in it.Consider following example with Node as parent class and MyNode as child class extending parent class Node.
//parent class public class Node<T> { public T data; public Node(T data) { this.data = data; } public void setData(T data) { System.out.println("Node.setData"); this.data = data; } } //child class public class MyNode extends Node<Integer> { public MyNode(Integer data) { super(data); } public void setData(Integer data) { // overrididng method System.out.println("MyNode.setData"); super.setData(data); } }After type erasure, the method signatures do not not match. The Node method becomes setData(Object) and the MyNode method becomes setData(Integer).
public void setData(T data) { .... } transformed to public void setData(Object data) { ... } and public void setData(Integer data) { ... } tranformed to public void setData(Integer data) {...}Therefore, the MyNode setData method does not override the Node setData method and doesn't preserve the polymorphism of generic types. Here Bridge method comes for rescue, Java compiler generate bridge method in child class and ensure that subtyping works as expected.See below diagram, we have bridge method generated in child class "setData(Object data) { }" overriding parent class method.
So, now bridge method delegates call to original setData(Integer) and maintains polymorphoism.
This is all about generics internal. Please refer this for understanding restriction in generics.
==========End of article=========
Happy learning
Nikhil
Đặt vé máy bay tại Aivivu, tham khảo
ReplyDeletegiá vé máy bay đi Mỹ khứ hồi
đã có chuyến bay từ mỹ về việt nam chưa
bay từ đức về việt nam mấy tiếng
giá vé máy bay nga về việt nam
vé máy bay từ anh về việt nam vietnam airlines
chuyến bay từ châu âu về việt nam
danh sách khách sạn cách ly tại tphcm
Chi phí cho chuyên gia nước ngoài
Mua vé tại đại lý vé máy bay Aivivu, tham khảo
ReplyDeletekinh nghiệm mua vé máy bay đi Mỹ giá rẻ
mua vé về việt nam
bao giờ có chuyến bay từ đức về việt nam
chuyến bay nhân đạo từ nga về việt nam
chuyến bay từ anh về việt nam
vé máy bay từ pháp về việt nam giá rẻ
giá khách sạn cách ly ở hà nội
chi phí vé máy bay cho chuyên gia nước ngoài
In Depth Concepts of Generics and explained neatly
ReplyDelete