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;
}
}
when a generic class is instantiated without specifying an actual type argument, the generic class is being used... where Point<T> is a generic type. When the method is called, the only Objects that may be passed for the perimeter p are...
A generic type used without type parameters is known as a raw type . Existing pre-5.0 code continues to work: you simply write all the casts that you're already used to writing, and you put up with some pestering from the compiler.
Due to the above conflict, instantiating a generic array in java is not permitted.
To use Java generics effectively, you must consider the following restrictions: Cannot Instantiate Generic Types with Primitive Types. Cannot Create Instances of Type Parameters. Cannot Declare Static Fields Whose Types are Type Parameters.
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With