The main objective of Generics is to provide type safety and to resolve type casting problems.
Case 1: Type-Safety:
Arrays are Type-safe i.e., we can give the guarantee for the type of elements present int the array.
For example, if our program requirement is only String type of Objects, we can choose String array, by mistake if we are trying to add any other type of objects we will get compile time error.
Hence String array can contain only String type of objects. Due to this we can give the guarantee for the type of elements present in the array. Hence arrays are safe to use w.r.to the type. i.e. Arrays are typesafe.
But Collections are not type-safe i.e., we can’t give the guarantee for type of elements present inside the Collections.
For example, if our programming requirement is to hold only String type Objects and if we choose ArrayList, by mistake if we are trying add any other type of object we won’t get any compile time error.
But the program may fail at runtime.
Hence, we can’t give the guarantee for the type of elements present inside the Collection. Due to this Collections are not safe to use w.r.to the type i.e., Collections are not Time-safe.
Case 2: Type-Casting:
In the case of Arrays at the time of retrieval is not required to perform type casting because there is guarantee for the type of elements present inside array.
But in the case of Collections at the time of retrieval compulsory we should perform type casting because there is no guarantee for the type of elements present in the Collections.
Hence Typecasting is mandatory in Collection.
To overcome above problems of Collection SUN people introduced Generics concept in 1.5V.
Hence the main objectives of Generics are
1. To provide Time-Safety.
2. To resolve Type-Casting problems
For example, to hold only String type objects we can create Generic version of ArrayList objects as follows
For this ArrayList we can add only String type objects. By mistake if we are trying to add any other type then we will get Compile time error
Hence through Generics we are getting type safety
At the time of retrieval, we are not required to perform type-casting
Hence through Generics we can solve type-casting problem.
Difference between ArrayList l = new ArrayList(); and ArrayList
ArrayList l = new ArrayList(); | ArrayList |
---|---|
It is a Non-Generic version of ArrayList object. | It is a Generic version of ArrayList object. |
For this ArrayList we can add any type of object and hence it is not Type-safe | For this ArrayList we can add only String type of object and hence it is Type-safe |
At the time of retrieval compulsory, we have to perform type-casting. | At the time of retrieval, we are not required to perform type-casting. |
Conclusion 1: Polymorphism concept applicable only for the Base type but not for parameter type.
(Usage of parent reference to hold child object is the concept of polymorphism);
Conclusion 2: For the type parameter we can provide any class or interface name but not primitive. If we are try to primitive then we will get compile time error.
Generic classes:
Until 1.4 Version a non-generic version of ArrayList class is declared as follows.
The argument2 add method is Object and hence we can add any type of Object to the ArrayList. Due tothis we are missing type safety.
The return type of get() method is Object. hence at the time of retrieval we have to perform type-casting.
But in 1.5 version a generic version of ArrayList class is declared as follows.
Based on our runtime requirement T will be replaced with our provided type.
For example, to hold only String type of Objects a Generic version of ArrayList objects can be creates as follows.
The argument 2 add() method is String type. Hence, we can add only String type of Objects. By mistake if we are trying to add any other type, we will get compile time error.
Hence through Generics we are getting type-safety.
the return type of get() method is String and hence at the time of retrieval we are not required to perform type-casting.
In Generics we are associating a type parameter to the class such type of parameter raised classes are nothing but Generic classes or Template classes.
Based on our requirement we can define our own Generic classes also.
Output:
The type of ob is java.lang.String
kalyan
The type of ob is java.lang.Integer
333
The type of ob is java.lang.Double
10.5
Bounded types:
We can bound the type parameter for a particular range by using extends keyword. Such types are called bounded types.
As the type parameter we can pass any type and there are no restrictions and hence it is unbounded type.
Syntax for Bounded Types:
'X' can be either class or interface.
If 'x' is a class then as a type parameter we can pass either 'x' type or its child classes
If 'x' is an interface then as a type parameter we can pass either 'x' type or its implementation classes.
For Example>
As type parameter we can take anything which should be child class of Number and should implements Runnable interface.
Note:
1. We can define bounded types only by using extends keyword and we can’t use implements and super keywords but we can replace implements keyword with extends keyword.
3. Based on our requirement we can declare any no. of type parameters and all these type parameters should be separated with ","(comma).
Generic methods and wild-card character(?):
we can call this method by passing ArrayList of only String type.
But within the method we can add only String type of Objects to the List. By mistake if we are trying to add any other type, we will get compile time error.
X can be either class or interface.
If X is the class, then we can call this method by passing ArrayList of either X type or its child classes
If X is the interface, then we can call this method by passing ArrayList of either X type or its implementation classes
But within the method we can’t add anything to the List except null because we don’t know the type exactly.
This type of method also best suitable for read only operation.
X can be either class or interface.
If X is the class, then we can call this method by passing ArrayList of either X type or its super classes
If X is the interface, then we can call this method by passing ArrayList of either X type or super class of implementation class of X.
But within the method we can add X type Objects and null to the List.
We can declare type parameter either at class level or method level.
Declaring type-parameter at class level:
Declaring type-parameter at method level:
we have to declare type-parameter just before return type.
we can define bounded types even at method levels also
Communication with non-generic code:
If we send generic object to non-generic area then it starts behaving like non generic object. similarly, if we send non-generic object to generic area then it starts behaving like generic object. i.e., the location in which the object present based on that behaviour will be defined.
Output:
[kalyan, chanukya, 10, 10.5, true]
The main purpose of Generics is to prob=vide type safety and to resolve type casting problems.
Type safety and type casting both are applicable at compile time hence Generics concept also applicable at only compile time but not at runtime.
At the time of compilation as last step Generic syntax will be removed and hence for JVM Generic syntax won’t be available
Output:
[10, 10.5, true]
Hence the following declarations are equal.
The following declarations are equal
At compile time:
1. Compile code normally by considering generic syntax.
2. Remove generic syntax.
3. Compile once again resultant code.
0 Comments