2. WHAT ARE GENERICS?
At its core, the term generics means
parameterized types. Parameterized types are
important because they enable you to create
classes, interfaces, and methods in which the
type of data upon which they operate is specified
as a parameter. Using generics, it is possible to
create a single class, for example, that
automatically works with different types of data.
A class,interface, or method that operates on a
parameterized type is called generic, as in generic
class or generic method.
BYLECTURERSURAJPANDEYCCT
COLLEGE
3. GENERIC METHODS
You can write a single generic method declaration that can be called with
arguments of different types. Based on the types of the arguments passed
to the generic method, the compiler handles each method call
appropriately. Following are the rules to define Generic Methods −
All generic method declarations have a type parameter section delimited
by angle brackets (< and >) that precedes the method's return type ( < E >
in the next example).
Each type parameter section contains one or more type parameters
separated by commas. A type parameter, also known as a type variable, is
an identifier that specifies a generic type name.
The type parameters can be used to declare the return type and act as
placeholders for the types of the arguments passed to the generic method,
which are known as actual type arguments.
A generic method's body is declared like that of any other method. Note
that type parameters can represent only reference types, not primitive
types (like int, double and char).
BYLECTURERSURAJPANDEYCCT
COLLEGE
4. Example
Following example illustrates how we can print
an array of different type using a single Generic
method −
BYLECTURERSURAJPANDEYCCT
COLLEGE
6. BOUNDED TYPE PARAMETERS
There may be times when you'll want to restrict the kinds
of types that are allowed to be passed to a type parameter.
For example, a method that operates on numbers might
only want to accept instances of Number or its subclasses.
This is what bounded type parameters are for.
To declare a bounded type parameter, list the type
parameter's name, followed by the extends keyword,
followed by its upper bound.
Example
Following example illustrates how extends is used in a
general sense to mean either "extends" (as in classes) or
"implements" (as in interfaces). This example is Generic
method to return the largest of three Comparable objects −
BYLECTURERSURAJPANDEYCCT
COLLEGE
8. Output
Max of 3, 4 and 5 is 5
Max of 6.6,8.8 and 7.7 is 8.8
Max of pear, apple and orange is pear
BYLECTURERSURAJPANDEYCCT
COLLEGE
9. GENERICS WORK ONLY WITH REFERENCE
TYPES
When declaring an instance of a generic type, the
type argument passed to the type parameter
must be a reference type. You cannot use a
primitive type, such as int or char.
For example, with Gen, it is possible to pass
any class type to T, but you cannot pass a
primitive type to a type parameter. Therefore,
the following declaration is illegal:
Gen<int> intOb = new Gen<int>(53); // Error,
can't use primitive type
BYLECTURERSURAJPANDEYCCT
COLLEGE
10. GENERIC CLASSES
A generic class declaration looks like a non-
generic class declaration, except that the class
name is followed by a type parameter section.
As with generic methods, the type parameter
section of a generic class can have one or more
type parameters separated by commas. These
classes are known as parameterized classes or
parameterized types because they accept one or
more parameters.
Example
Following example illustrates how we can define
a generic class −
BYLECTURERSURAJPANDEYCCT
COLLEGE
13. A GENERIC CLASS WITH TWO TYPE
PARAMETERS
You can declare more than one type parameter in
a generic type. To specify two or more type
parameters, simply use a comma-separated list.
For example, the following TwoGen class is a
variation of the Gen class that has two type
parameters:
BYLECTURERSURAJPANDEYCCT
COLLEGE
14. // A simple generic class with two type
// parameters: T and V.
class TwoGen<T, V> {
T ob1;
V ob2;
// Pass the constructor a reference to
// an object of type T and an object of type V.
TwoGen(T o1, V o2) {
ob1 = o1;
ob2 = o2;
}
// Show types of T and V.
void showTypes() {
System.out.println("Type of T is " +
ob1.getClass().getName());
System.out.println("Type of V is " +
ob2.getClass().getName());
}
T getob1() {
return ob1;
}
BYLECTURERSURAJPANDEYCCT
COLLEGE
15. V getob2() {
return ob2;
}
}
// Demonstrate TwoGen.
class SimpGen {
public static void main(String args[]) {
TwoGen<Integer, String> tgObj =
new TwoGen<Integer, String>(88, "Generics");
// Show the types.
tgObj.showTypes();
// Obtain and show values.
int v = tgObj.getob1();
System.out.println("value: " + v);
String str = tgObj.getob2();
System.out.println("value: " + str);
}
}
BYLECTURERSURAJPANDEYCCT
COLLEGE
16. The output from this program is shown here:
Type of T is java.lang.Integer
Type of V is java.lang.String
value: 88
value: Generics
BYLECTURERSURAJPANDEYCCT
COLLEGE
17. Notice how TwoGen is declared:
class TwoGen<T, V> {
It specifies two type parameters: T and V, separated by a
comma. Because it has two type parameters, two type
arguments must be passed to TwoGen when an object is
created, as shown next:
TwoGen<Integer, String> tgObj = new TwoGen<Integer,
String>(88, "Generics");
In this case, Integer is substituted for T, and String is
substituted for V.
Although the two type arguments differ in this example, it is
possible for both types to be the same. For example, the following
line of code is valid:
TwoGen<String, String> x = new TwoGen<String, String> ("A",
"B");
In this case, both T and V would be of type String. Of course, if
the type arguments were always the same, then two type
parameters would be unnecessary.
BYLECTURERSURAJPANDEYCCT
COLLEGE
18. THE GENERAL FORM OF A GENERIC
CLASS
The generics syntax shown in the preceding
examples can be generalized. Here is the
syntax for declaring a generic class:
class class-name<type-param-list > { // …
Here is the full syntax for declaring a reference
to a generic class and instance creation:
class-name<type-arg-list > var-name = new class-
name<type-arg-list >(cons-arg-list);
BYLECTURERSURAJPANDEYCCT
COLLEGE
19. Bounded Types
In the preceding examples, the type parameters
could be replaced by any class type. This is fine
for many purposes, but sometimes it is useful to
limit the types that can be passed to a type
parameter. For example, assume that you want
to create a generic class that contains a method
that returns the average of an array of numbers.
Furthermore, you want to use the class to obtain
the average of an array of any type of number,
including integers, floats, and doubles. Thus,
you want to specify the type of the numbers
generically, using a type parameter.
BYLECTURERSURAJPANDEYCCT
COLLEGE
20. To create such a class, you might try something like this:
// Stats attempts (unsuccessfully) to
// create a generic class that can compute
// the average of an array of numbers of
// any given type.
//
// The class contains an error!
class Stats<T> {
T[] nums; // nums is an array of type T
// Pass the constructor a reference to
// an array of type T.
Stats(T[] o) {
nums = o;
}
// Return type double in all cases.
double average() {
double sum = 0.0;
for(int i=0; i < nums.length; i++)
sum += nums[i].doubleValue(); // Error!!!
return sum / nums.length;
}
}
BYLECTURERSURAJPANDEYCCT
COLLEGE
21. Creating a Generic Method
As the preceding examples have shown, methods
inside a generic class can make use of a class’
type parameter and are, therefore, automatically
generic relative to the type parameter.
However, it is possible to declare a generic
method that uses one or more type parameters of
its own. Furthermore, it is possible to create a
generic method that is enclosed within a non-
generic class.
BYLECTURERSURAJPANDEYCCT
COLLEGE
22. Let’s begin with an example. The following
program declares a non-generic class called
GenMethDemo and a static generic method
within that class called isIn( ). The isIn( )
method determines if an object is a member of an
array. It can be used with any type of object and
array as long as the array contains objects that
are compatible with the type of the object being
sought.
BYLECTURERSURAJPANDEYCCT
COLLEGE
23. // Demonstrate a simple generic method.
class GenMethDemo {
// Determine if an object is in an array.
static <T extends Comparable<T>, V extends T> boolean isIn(T x,
V[] y) {
for(int i=0; i < y.length; i++)
if(x.equals(y[i])) return true;
return false;
}
public static void main(String args[]) {
// Use isIn() on Integers.
Integer nums[] = { 1, 2, 3, 4, 5 };
if(isIn(2, nums))
System.out.println("2 is in nums");
if(!isIn(7, nums))
System.out.println("7 is not in nums");
System.out.println();
BYLECTURERSURAJPANDEYCCT
COLLEGE
24. // Use isIn() on Strings.
String strs[] = { "one", "two", "three", "four", "five"
};
if(isIn("two", strs))
System.out.println("two is in strs");
if(!isIn("seven", strs))
System.out.println("seven is not in strs");
// Oops! Won't compile! Types must be
compatible.
// if(isIn("two", nums))
// System.out.println("two is in strs");
}
}
BYLECTURERSURAJPANDEYCCT
COLLEGE
25. The output from the program is shown here:
2 is in nums
7 is not in nums
two is in strs
seven is not in strs
BYLECTURERSURAJPANDEYCCT
COLLEGE
26. Generic Types
A generic type is a generic class or interface that is
parameterized over types. The following Box class will be
modified to demonstrate the concept.
A Simple Box Class
Begin by examining a non-generic Box class that operates on
objects of any type. It needs only to provide two methods: set,
which adds an object to the box, and get, which retrieves it:
public class Box { private Object object; public void set(Object
object) { this.object = object; } public Object get() { return
object; } }
Since its methods accept or return an Object, you are free to
pass in whatever you want, provided that it is not one of the
primitive types. There is no way to verify, at compile time,
how the class is used. One part of the code may place an
Integer in the box and expect to get Integers out of it, while
another part of the code may mistakenly pass in a String,
resulting in a runtime error.
BYLECTURERSURAJPANDEYCCT
COLLEGE
27. Type Parameter Naming Conventions
By convention, type parameter names are single,
uppercase letters. This stands in sharp contrast to the
variable naming conventions that you already know
about, and with good reason: Without this convention,
it would be difficult to tell the difference between a
type variable and an ordinary class or interface name.
The most commonly used type parameter names are:
E - Element (used extensively by the Java Collections
Framework)
K - Key
N - Number
T - Type
V - Value
S,U,V etc. - 2nd, 3rd, 4th types
BYLECTURERSURAJPANDEYCCT
COLLEGE
28. Hierarchy and classification
According to Java Language Specification:
A type variable is an unqualified identifier. Type variables are introduced by generic class
declarations, generic interface declarations, Generic method declarations, and by generic
constructor declarations.
A class is generic if it declares one or more type variables. These type variables are known
as the type parameters of the class. It defines one or more type variables that act as
parameters. A generic class declaration defines a set of parameterized types, one for each
possible invocation of the type parameter section. All of these parameterized types share
the same class at runtime.
An interface is generic if it declares one or more type variables. These type variables are
known as the type parameters of the interface. It defines one or more type variables that
act as parameters. A generic interface declaration defines a set of types, one for each
possible invocation of the type parameter section. All parameterized types share the same
interface at runtime.
A method is generic if it declares one or more type variables. These type variables are
known as the formal type parameters of the method. The form of the formal type parameter
list is identical to a type parameter list of a class or interface.
A constructor can be declared as generic, independently of whether the class that the
constructor is declared in is itself generic. A constructor is generic if it declares one or more
type variables. These type variables are known as the formal type parameters of the
constructor. The form of the formal type parameter list
is identical to a type parameter list of a generic class or interface.
BYLECTURERSURAJPANDEYCCT
COLLEGE
29. The Java Generics programming is introduced
in J2SE 5 to deal with type-safe objects.
Before generics, we can store any type of objects
in collection i.e. non-generic. Now generics, forces
the java programmer to store specific type of
objects.
BYLECTURERSURAJPANDEYCCT
COLLEGE
30. Advantage of Java Generics
There are mainly 3 advantages of generics. They are as
follows:
1) Type-safety : We can hold only a single type of objects
in generics. It doesn’t allow to store other objects.
2) Type casting is not required: There is no need to
typecast the object.
Before Generics, we need to type cast.
1. List list = new ArrayList();
2. list.add("hello");
3. String s = (String) list.get(0);//typecasting
After Generics, we don't need to typecast the object.
1. List<String> list = new ArrayList<String>();
2. list.add("hello");
3. String s = list.get(0);
BYLECTURERSURAJPANDEYCCT
COLLEGE
31. 3) Compile-Time Checking: It is checked at
compile time so problem will not occur at
runtime. The good programming strategy says it
is far better to handle the problem at compile
time than runtime.
1. List<String> list = new ArrayList<String>();
2. list.add("hello");
3. list.add(32);//Compile Time Error
Syntax to use generic collection
ClassOrInterface<Type>
Example to use Generics in java
ArrayList<String>
BYLECTURERSURAJPANDEYCCT
COLLEGE
32. FULL EXAMPLE OF GENERICS IN
JAVA
Here, we are using the ArrayList class, but you
can use any collection class such as ArrayList,
LinkedList, HashSet, TreeSet, HashMap,
Comparator etc.
BYLECTURERSURAJPANDEYCCT
COLLEGE
33. import java.util.*;
class TestGenerics1{
public static void main(String args[]){
ArrayList<String> list=new ArrayList<String>();
list.add("rahul");
list.add("jai");
//list.add(32);//compile time error
String s=list.get(1);//type casting is not required
System.out.println("element is: "+s);
Iterator<String> itr=list.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:element is: jai
rahul
jai
BYLECTURERSURAJPANDEYCCT
COLLEGE
34. Example of Java Generics using Map
Now we are going to use map elements using
generics. Here, we need to pass key and value.
Let us understand it by a simple example:
BYLECTURERSURAJPANDEYCCT
COLLEGE
35. import java.util.*;
class TestGenerics2{
public static void main(String args[]){
Map<Integer,String> map=new HashMap<Integer,String>();
map.put(1,"vijay");
map.put(4,"umesh");
map.put(2,"ankit");
//Now use Map.Entry for Set and Iterator
Set<Map.Entry<Integer,String>> set=map.entrySet();
Iterator<Map.Entry<Integer,String>> itr=set.iterator();
while(itr.hasNext()){
Map.Entry e=itr.next();//no need to typecast
System.out.println(e.getKey()+" "+e.getValue());
}
}}
Output:1 vijay
2 ankit
4 umesh
BYLECTURERSURAJPANDEYCCT
COLLEGE
36. GENERIC CLASS
A class that can refer to any type is known as
generic class. Here, we are using T type
parameter to create the generic class of specific
type.
Let’s see the simple example to create and use
the generic class.
BYLECTURERSURAJPANDEYCCT
COLLEGE
37. Creating generic class:
class MyGen<T>{
T obj;
void add(T obj){this.obj=obj;}
T get(){return obj;}
}
The T type indicates that it can refer to any type
(like String, Integer, Employee etc.). The type
you specify for the class, will be used to store and
retrieve the data.
BYLECTURERSURAJPANDEYCCT
COLLEGE
38. Using generic class:
Let’s see the code to use the generic class.
class TestGenerics3{
public static void main(String args[]){
MyGen<Integer> m=new MyGen<Integer>();
m.add(2);
//m.add("vivek");//Compile time error
System.out.println(m.get());
}}
Output:2
BYLECTURERSURAJPANDEYCCT
COLLEGE
39. Type Parameters
The type parameters naming conventions are
important to learn generics thoroughly. The
commonly type parameters are as follows:
T - Type
E - Element
K - Key
N - Number
V - Value
BYLECTURERSURAJPANDEYCCT
COLLEGE
40. Generic Method
Like generic class, we can create generic method
that can accept any type of argument.
Let’s see a simple example of java generic
method to print array elements. We are using
here E to denote the element.
BYLECTURERSURAJPANDEYCCT
COLLEGE
41. public class TestGenerics4{
public static < E > void printArray(E[] elements) {
for ( E element : elements){
System.out.println(element );
}
System.out.println();
}
public static void main( String args[] ) {
Integer[] intArray = { 10, 20, 30, 40, 50 };
Character[] charArray = { 'J', 'A', 'V', 'A', 'T','P','O','I','N','T'
};
System.out.println( "Printing Integer Array" );
printArray( intArray );
System.out.println( "Printing Character Array" );
printArray( charArray );
}
}
BYLECTURERSURAJPANDEYCCT
COLLEGE
42. Output:Printing Integer Array
10
20
30
40
50
Printing Character Array
J
A
V
A
T
P
O
I
N
T
BYLECTURERSURAJPANDEYCCT
COLLEGE