Java

TOPIC 18 – GENERICS

 

 

LESSON NOTE

 

 

WHY NOW?

 

We need to learn about Generics now so that we can make use of the built-in data structures in the Java Collections.  This lesson will prepare us for that.

 

OBJECT CLASS (REVIEW)

 

All classes in Java automatically extend the Object class.  By consequence, all objects inherit all datafields & methods in the Object class.  Recall that the toString() method can be called on any object – that is because it is in the Object class and is inherited.

 

Using polymorphism, we can also do this:

 

          Object obj = new AnyClass();

 

OBJECT DATAFIELD

 

When creating a class, we can have a datafield of type Object.  This can in turn actually hold any type of object.

 

EXAMPLE

Below is a class that has one datafield of type Object.  Because Object is the superclass of all other classes, it can actually hold any type of object.

public class Box
{

    private Object obj;

 

    public Box(Object o)

    {

        obj = o;

    }

 

    public void set(Object o)

    {

        obj = o;

    }

   

    public Object get()

    {

        return obj;

    }

}

 

So, each of the following are allowed:

 

Point p = new Point(5,4);

Box a = new Box(p);

 

String s = new String("yo");

Box b = new Box(s);

 

Rectangle r = new Rectangle(10,14,20,25);

Box c = new Box(r);

 

The point is that we can now create a Box object using any type of object to be stored inside it.

 

Also, to get our stored object from inside the box object, we do need to use typecasting:

 

Point pt = (Point)a.get();

 

String str = (String)b.get();

 

Rectangle rect = (Rectangle)c.get();

 

 

Being able to create a class that can hold any type of object is very useful – especially when it comes to specialized classes that are used specifically to organize different types of data (aka, data structures).

 

PROBLEM

 

The above approach works well.  It doesn't include any generics.  So why do we need generics?

 

There is a problem that arises with the above situation.  Because the Object datafield can be any object, Java has no way of testing if the programmer is being consistent.  So the user might be storing a String and then expecting a Point from that datafield. 

 

That error would only be caught at run-time and can lead to complications.  So, as Java continued to evolve, the idea of generics was included to deal with this problem.

 

GENERICS

 

The concept of generics allows us to specify a consistent type of data that will be used throughout a class.  Classes that use generics are called generic classes and are declared in the following way:

 

public className<T>

{

  

}

 

Where T specifies the type of the data that will be used.  So, anywhere in the class, we can use T to ensure consistency in regards to the data type.

 

EXAMPLE

 

Below is the same Box class as in the example above but using generics.

 

public class Box<T>
{

    private T obj;

 

    public Box(T o)

    {

        obj = o;

    }

 

    public void set(T o)

    {

        obj = o;

    }

   

    public T get()

    {

        return obj;

    }

}

 

Now, we can create Box objects using this approach:

 

Point p = new Point(5,4);

Box<Point> a = new Box<Point>(p);

 

String s = new String("yo");

Box<String> b = new Box<String>(s);

 

Rectangle r = new Rectangle(10,14,20,25);

Box<Rectangle> c = new Box<Rectangle>(r);

 

And we can get the datafield object without typecasting.

 

Point pt = a.get();

 

String str = b.get();

 

Rectangle rect = c.get();

 

 

NAMING CONVENTION

 

Does the generic parameter inside the class have to be "T"?  No, it doesn't.  It can be anything.  However, java convention is to use a single upper case letter.  And T is used most because it is short for "type".

 

MULTIPLE GENERIC PARAMETERS

 

You can have multiple generic paramaters if you'd like.  A generic class with two generic parameters would look like:

 

public className<T, U>

{

  

}

 

And inside the class, T and U would be used to refer to the two types specified when the object was created.

 

EXAMPLE

 

Below is a class called Pair that simply holds two objects of any types (not necessarily the same type).

 

public class Pair<T, U> 
{
    private T obj1;
    private U obj2;
 
    public Pair(T o1, U o2)
    {
        obj1 = o1;
        obj2 = o2;
    }
 
    public T get1()
    {
        return obj1;
    }
 
    public U get2()
    {
        return obj2;
    }
 
    public void set1(T object)
    {
       obj1 = object;
    }
 
    public void set2(U object)
    {
        obj2 = object;
    }
}
 
We can now create Pair objects like so:
 
String s = "hi";
Point p = new Point(2,4);
 
Pair<String, Point> sp = new Pair<String, Point>(s, p);
 
Inside the class, T would be replaced by String and U would be replaced by Point.

 

 

Source: https://docs.oracle.com/javase/tutorial/java/generics/types.html