In the code below, if I instantiate Generic as:
Generic gen=new Generic(1,2);
that is without type argument,then when i do this:
int a=gen.get_a();
it does not work and gives
required:int Found:Java.Lang.Object
but ob.print()
works.
So when I do this instead:
int a=(Integer)gen.get_a();
then it works. So does the erasure replace T
with Object
type since T
cannot be primitive, when no type argument is passed?
public class Generic<T>
{
T a;
Generic(T a)
{
this.a=a;
}
void print()
{
System.out.print(a);
}
T get_a()
{
return a;
}
}
Here, as Jon Skeet said, you are using a raw type in your variable declaration.
Generic gen=new Generic(1,2);
int a=gen.get_a();
it does not work and gives
required:int Found:Java.Lang.Object
The compiler cannot guess the type if you don't specify it when you declare the variable.
So does the erasure replace T with Object type since T cannot be
primitive, when no type argument is passed?
Using types demands specifying class in the declaration. And a primitive is not a class.
Generic<int> gen = new Generic<>(1);
will not compile
So, you have to specify the wrapper object of int primitive if you want to type your instance with an integer value :
Generic<Integer> gen = new Generic<>(1);
You must have done noticed it when you declare a collection variable with generics relying on numeric types.
Object
is the root class in Java and as in your caseT
doesn't extend any explicit class, T
derives from Object
implicitly.
So, it you use a raw type in your variable, you manipulate objects.
I suppose that the compiler considers that the returned type of unspecified T
is the most specific and compatible type for T
and in your case it is Object
.
You have the same behavior with a collection : at compile-time, a raw java.util.List
manipulates Object
when T
is encountered.
Edit :
Here, I will give you another example to illustrate that with raw types, instead of declare type, the Object
class is not necessarily used by the compiler if the type declared in the class extends another class. Contrary to what you may think.
If the Generic
class was declared like that :
public class Generic<T extends MyClass>{
...
}
Even by using a raw type in the declaration of the variable, get_a()
would return a MyClass
object since the most specific and compatible type for T
is not Object
but MyClass
.
Generic gen = new Generic(1);
MyClass myClass = gen.get_a(new MyClass());