Generics

These are introduced by JDK5 which adds two features as follows

  1. added a new syntactical element to the language.

  2. caused changes to many of the classes and methods in the core API.

  3. we can create classes, interfaces, and methods that will work in a type-safe manner with various kinds of data means we can create an algorithm to any specific type of data we can use this for any type of data with no effort.

  4. In Java the most significantly affected by generics is the Collections Framework which is a part of java API.

  5. A collection is a group of objects. The Collections Framework defines several classes, such as lists and maps, that manage collections.

  6. These classes are designed in a way that to be able to work with any type of object.

Meaning of Generics

  • The term generics means parameterized types.
  • They enable us to create classes,interfaces, and methods in which the type of data upon which they operate is specified as a parameter.

  • A class, interface, or method that operates on a parameterized type is called generic,as in generic class or generic method.

  • We can create a class which operates on all types of data

  • This can be done by the reference of Object which holds the data of as Class, predefined data types.

The General Form of a Generic Class

  • the syntax for declaring a generic class:

class class-name { // …

  • full syntax for declaring a reference to a generic class and instance creation:

class-name var-name = new class-name(cons-arg-list);

// A simple generic class.
// Here, T is a type parameter that
// will be replaced by a real type
// when an object of type Gen is created.
class Gen<T> 
{
 T ob; // declare an object of type T
 // Pass the constructor a reference to an object of type T.
 Gen(T o) 
{
 ob = o;
 }
 // Return ob.
 T getob() 
{
 return ob;
 }
 // Show type of T.
void showType() 
{
 System.out.println("Type of T is " + ob.getClass().getName());
 }
}
// Demonstrate the generic class.
public class Simple 
{
 public static void main(String args[]) 
{
 // Create a Gen reference for Integers.
 Gen<Integer> iOb;
 // Create a Gen<Integer> object and assign its reference to iOb. Notice the use of //autoboxing
 // to encapsulate the value 88 within an Integer object.
 iOb = new Gen<Integer>(88);  //(88.0) is error as it is not integer
 // Show the type of data used by iOb.
 iOb.showType();
 // Get the value in iOb. Notice that no cast is needed.
 int v = iOb.getob();
 System.out.println("value: " + v);
 System.out.println();

 // Create a Gen object for Strings.
 Gen<String> strOb = new Gen<String> ("Generics Test");
 // Show the type of data used by strOb.
 strOb.showType();
 // Get the value of strOb. Again, notice
 String str = strOb.getob();
 System.out.println("value: " + str);
 }
}

Output:

Type of T is java.lang.Integer

value: 88

Type of T is java.lang.String

value: Generics Test

Generics Work Only with Reference Types

  • The type argument passed to the generic must be a reference type not a primitive type

Gen intOb = new Gen(53); //error

Generic Types Differ Based on Their Type Arguments

  • one specific version of a generic type is not type compatible with another version of the same generic type.

iOb = strOb; // Wrong!

Thus generics add type safety and prevent errors.

How Generics Improve Type Safety

generic Gen class can be achieved without generics, by simply specifying Object as the data type and employing the proper casts.

// NonGen is functionally equivalent to Gen
// but does not use generics.
class NonGen {
 Object ob; // ob is now of type Object
 // Pass the constructor a reference to
 // an object of type Object
 NonGen(Object o) {
 ob = o;
 }
 // Return type Object.
 Object getob() {
 return ob;
 }
 // Show type of ob.
 void showType() {
 System.out.println("Type of ob is " + ob.getClass().getName());
 }
}
// Demonstrate the non-generic class.
public class Simple {
 public static void main(String args[]) {
 NonGen iOb;
 // Create NonGen Object and store
 // an Integer in it. Autoboxing still occurs.
 iOb = new NonGen(88);
 // Show the type of data used by iOb.
 iOb.showType();
 // Get the value of iOb.
 // This time, a cast is necessary.
 int v = (Integer) iOb.getob();
 System.out.println("value: " + v);
 System.out.println();
 // Create another NonGen object and
 // store a String in it.
 NonGen strOb = new NonGen("Non-Generics Test");
 // Show the type of data used by strOb.
 strOb.showType();
 // Get the value of strOb.
 // Again, notice that a cast is necessary.
 String str = (String) strOb.getob();
 System.out.println("value: " + str);
 // This compiles, but is conceptually wrong!
 iOb = strOb;
 v = (Integer) iOb.getob(); // run-time error!
 }
}

Output:

Type of ob is java.lang.Integer

value: 88

Type of ob is java.lang.String

value: Non-Generics Test

Here there are two drawbacks for using non generics as follows

  • explicit casts must be employed to retrieve the stored data.

int v = (Integer) iOb.getob();

In generics it will be implicit but in non generic it is explicit.

  • many kinds of type mismatch errors cannot be found until run time.

// This compiles, but is conceptually wrong!

iOb = strOb;

v = (Integer) iOb.getob(); // run-time error!

A Generic Class with Two Type Parameters

  • We can declare more than one type parameter in a generic type by simply using comma in the parameter list.
// 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;
 }
 V getob2() 
{
 return ob2;
 }
}
// Demonstrate TwoGen.
public class Simple
{
 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);
 }
}

Output:

Type of T is java.lang.Integer

Type of V is java.lang.String

value: 88

value: Generics

results matching ""

    No results matching ""