kai
kai

Reputation: 6887

problems with understanding generics

I have wrote the following code:

public class Test
{   
    public static void main(String args[]) throws ParseException 
    {
        System.out.println(new Generic<Integer>("one").type);  //outputs "one"
    }
}

class Generic<T>
{
    public T type;

    public Generic(Object obj)
    {
        type = (T)obj;
    }
}

And i thought i will get an exception while doing the cast, but i didnt. I get the output: "one". But if i do new generic<Integer>, type become a variable of type Integer, so how can i cast the String "one" to T and store it in the variable type in my generic class without getting an exception? An explanation would be great.

Upvotes: 3

Views: 86

Answers (4)

Hirak
Hirak

Reputation: 3649

It is not casting your string to integer....because it is unbound. It is converting the T to object instead and in the sysout you are getting obj.toString instead.

The proper way would be as below and automatically you will get compile exception in your test class... as expected.

class Generic<T>
{
    public T type;

    public Generic(T t)
    {
        type = t;

    }
}

Upvotes: 0

Paul Bellora
Paul Bellora

Reputation: 55233

There is no exception because type erasure removes any checking of the Integer type from your code. Since println takes Object the compiler doesn't need to insert a cast, and the code simply erases to:

System.out.println(new Generic("one").type);

Try the following assignment instead:

Integer i = new Generic<Integer>("one").type;

In that case you'll get a ClassCastException because the code erases to:

Integer i = (Integer)new Generic("one").type;

Notice that switching the types behaves differently. This will throw a ClassCastException:

System.out.println(new Generic<String>(123).type);

That's because the println(String) overload is used, so the code erases to:

System.out.println((String)new Generic(123).type);

Upvotes: 4

Mikkel L&#248;kke
Mikkel L&#248;kke

Reputation: 3749

class Generic<T>
{
    public T type;

    public Generic(T obj)
    {
        type = obj;
    }
}

There. Fixed it for you.

Upvotes: -1

light_303
light_303

Reputation: 2111

This is because of java type erasure: http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

basically java will replace T with Object (if T has no bounding upper type like in your example)- and everything is fine at runtime.

Upvotes: 1

Related Questions