Pages

Wednesday, August 12, 2020

Raw type Generics in Java - Working Examples

1. Raw type Generics in Java 


Raw Type is part of Java Generics. Raw Type is If any generic class reference or instance is created without mentioning the proper Type for the Generic type. Reference indicates to Class or Interface.

Generics in Java

Generics naming conventions and rules

Generics main aim to provide tighter type checks at compile time.

Raw type in Java Generics with Examples




Please go through the following basic example program.


2. Java Raw Type Example:



package com.adeepdrive.generics;

public class RawTypeExample {

    public static void main(String[] args) {

        RawType<String> genericObj = new RawType<String>();
        genericObj.setT("Generic Object");
        System.out.println("Generic Object created String type. It's value : " + genericObj.getT());

        RawType rawType = new RawType(); // Legal, but it will give warnings.
        rawType.setT(new Integer(20));
        System.out.println("Raw Type Generic Object creage. It's value : " + rawType.getT());
    }
}

class RawType<T> {
    T t;
    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

Output:

Generic Object created String type. It's value : Generic Object
Raw Type Generic Object creage. It's value : 20

In the above program, we have created a generic class "RawType" and then created an object for RawType by passing generic type String. Which is legal against Generic rules.

Second, Created another object for RawType class but did not pass any Generic type to it. That means we can set any value to it. That can be String, Integer, List or any class. In our example, we passed Integer instance. Compiler will give warning but safe.

Oracle Java Raw Types Guide.

3. Reassigning RawType instances example:


package com.adeepdrive.generics;
public class RawTypeExample2 {
    public static void main(String[] args) {

        RawType rawTypeObj1 = null;
        rawTypeObj1 = new RawType();
        rawTypeObj1.setT(new Integer(20));
        System.out.println("rawTypeObj1 value : " + rawTypeObj1.getT());
    
        RawType rawTypeObj2 = new RawType();
        rawTypeObj2.setT(new Integer(20));
        System.out.println("rawTypeObj2 value : " + rawTypeObj2.getT());
      
        rawTypeObj1 = rawTypeObj2;
        System.out.println("rawTypeObj1 value : " + rawTypeObj1.getT());
    }
}

Output:

rawTypeObj1 value : 20
rawTypeObj2 value : 20
rawTypeObj1 value : 20

The above program compiles and runs fine.

RawType rawTypeObj1 = null;
rawTypeObj1 = new RawType();
       
First, created raw type reference rawTypeObj1 and object without passing type to it. This means, compiler does not know what type should be added to it. So, we can add any type of object. Compile will not give error at this point. Compilation is fine.

Next, create new object by passing type as String while creating object for RawType.

RawType rawTypeObj2 = new RawType<String>();

new RawType<String>(): This object knows about String type but reference rawTypeObj2 has no idea about type. In next line, we have set the integer. Which is perfectly right. This is similar to the rawTypeObj1. we can set any object to rawTypeObj2. Here also no error.

4. Error or Invalid Example:


RawType<String> rawTypeObj2 = new RawType<String>();
rawTypeObj2.setT(new Integer(20));

In the above example, We have created an object with generic type as String (Reference side and object creation side). But next, set Integer object to it which gives compile time error message as following.

The method setT(String) in the type RawType<String> is not applicable for the arguments (Integer)

5. Tricky Example:


package com.adeepdrive.generics;

public class RawTypeTricky {
    public static void main(String[] args) {
        Color<String> colorOne = new Color();

        Color colorTwo = colorOne;
        colorTwo.setType(100);
         System.out.println("colorTwo value : " + colorTwo.getType());
    }
}

class Color<T> {
    T type;
     public T getType() {
        return type;
    }

    public void setType(T type) {
        this.type = type;
    }
}

This is tricky, Guess the output of this program.

Program compile and runs fine but will give warnings.
Type safety: The expression of type Color needs unchecked conversion to conform to Color<String>

Output:

colorTwo value : 100

6. What is difference between ArrayList and ArrayList<?>?


If we create object using these two methods, both seems to be adding anything is allowed.

ArrayList list = new ArrayList();
list.add("Jhon");
list.add(10);
list.add(new HashMap());

Above code is valid.

ArrayList<?> list2 = list;
System.out.println("list2 size : "+list2.size());
       
Output:

list2 size : 3

list2.add("Cena");
But when add any object or value to list2 then will give compile time error. Because list2 is pointing to wildcard (?) which means list2 does not know what type of objects to be added to it.

Here, list2 becomes read only arraylist.

Most of the cases and as per the collection classes usage, wild card(?) is used with extends keyword as below.

ArrayList<? extends Number> list = new ArrayList<Integer>();

API

No comments:

Post a Comment

Please do not add any spam links in the comments section.