Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between these statements in a generic class?

Tags:

java

generics

I am still learning about generics and have a question. Say you had this generic class:

public class Test<T> {

    public static void main (String[] args) {
        Test t1 = new Test();
        Test<String> t2 = new Test<String>();
        Test t3 = new Test<String>();
    }
}

All the statements compile but I don't really know what makes them different. Can anyone give me a brief explanation on those three statements.

like image 429
user1420042 Avatar asked Feb 22 '13 11:02

user1420042


People also ask

What is difference between class and generic class?

The generic class works with multiple data types. A normal class works with only one kind of data type.

What are generic classes?

Generic classes encapsulate operations that are not specific to a particular data type. The most common use for generic classes is with collections like linked lists, hash tables, stacks, queues, trees, and so on.

What is difference between extends and super in generics?

super is a lower bound, and extends is an upper bound.


3 Answers

Test t1 = new Test();

Here you are using a Raw type. i.e., not passing an Type argument for your generic class.

Compiler should give you a warning here

Test is a raw type. References to generic type Test should be parameterized

    Test<String> t2 = new Test<String>();

here you are using generics. passing String as a type argument to your generic class.

    Test t3 = new Test<String>();

compiler should also give you a warning here too :

  • Test is a raw type. References to generic type Test should be parameterized

same as your first case, but you are using parameterized type while invoking the constructor.

There is also another class which works fine in +java 7 versions.

    Test<String> t4 = new Test<>();

No compiler warning here if you use + java 7 due to Type Inference

In this case due to introduction of type inference generic type is inferred, thus you don't need to provide the generic type during constructor invokation.

like image 168
PermGenError Avatar answered Nov 03 '22 09:11

PermGenError


Generics give you compile-time type checks.

It helps to add examples of what you can/can't do with your items (I've changed Test to ArrayList for ease of examples):

    ArrayList t1 = new ArrayList();
    ArrayList<String> t2 = new ArrayList();
    ArrayList t3 = new ArrayList<String>();

    // First list can have ANYTHING added to it
    // Compiler won't check because no generics
    t1.add(new Integer("7"));
    t1.add("Hello");

    // Second list can only have Strings added to it
    // Compiler will check and throw compile error for anything else
    t2.add(new Integer("7"));   // doesn't compile
    t2.add("Hello");

    // Third list is interesting...
    // Again, can have ANYTHING added to it
    // This is because generics (in Java...) are swapped out at COMPILE time
    //   rather than RUNTIME. The compiler can see that the actual type is just
    //   plain ArrayList
    // If you like, it's similar to doing: 
    //   Object o = (String) new Object(); 
    // The net-effect is everything reduced back to Object
    t3.add(new Integer("7"));  // fine
    t3.add("Hello");
like image 28
David Lavender Avatar answered Nov 03 '22 08:11

David Lavender


They all actually create identical objects. The only difference will be how they are treated syntactically in the rest of the code.

t1 and t3 will be treated in exactly the same way because they are the same type - they will be treated as an object with class Test, nothing more.

t2 will be treated more rigorously in terms of type checking. If some opportunity presents itself for the compiler to make use of its generic <String> quality then that quality will also be required to match.

like image 20
OldCurmudgeon Avatar answered Nov 03 '22 10:11

OldCurmudgeon