简体   繁体   中英

Java Generic Class Instantiation without Type Argument

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 case T 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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM