Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generic Class Instantiation without Type Argument

Tags:

java

generics

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;
    }
}
like image 205
Deepayan Ghosh Avatar asked Jan 03 '17 11:01

Deepayan Ghosh


People also ask

Can a generic class be instantiated without specifying an actual type argument?

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...

When a Java generic type is instantiated without any type of parameter it is known as?

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.

Can you instantiate a generic class in Java?

Due to the above conflict, instantiating a generic array in java is not permitted.

Can you instantiate a generic type?

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.


1 Answers

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());
like image 160
davidxxx Avatar answered Oct 11 '22 14:10

davidxxx