简体   繁体   English

没有类型参数的Java通用类实例化

[英]Java Generic Class Instantiation without Type Argument

In the code below, if I instantiate Generic as: 在下面的代码中,如果我将Generic实例化为:

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 required:int Found:Java.Lang.Object

but ob.print() works. 但是ob.print()有效。 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? 因此,当没有传递类型参数时,删除会将T替换为Object类型,因为T不能是原始的吗?

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. 在这里,正如Jon Skeet所说,你在变量声明中使用了原始类型。

 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? 因此,当没有传递类型参数时,删除会将T替换为对象类型,因为T不能是原始的吗?

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); 因此,如果要使用整数值键入实例,则必须指定int primitive的包装器对象: 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. Object是Java中的根类,在您的情况下, T不扩展任何显式类, T隐式地从Object派生。
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 . 我想,编译器认为,未指定的返回类型T是最具体和兼容类型T ,并在你的情况下,它是Object
You have the same behavior with a collection : at compile-time, a raw java.util.List manipulates Object when T is encountered. 对集合有相同的行为:在编译时,原始java.util.List在遇到T时操纵Object


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. 编辑 :在这里,我将举一个例子来说明使用原始类型而不是声明类型,如果类中声明的类型扩展另一个类,则编译器不一定使用Object类。 Contrary to what you may think. 与你的想法相反。

If the Generic class was declared like that : 如果Generic类被声明为:

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 . 即使在变量声明中使用原始类型, get_a()也会返回一个MyClass对象,因为T的最具体和兼容的类型不是Object而是MyClass

 Generic gen = new Generic(1);
 MyClass myClass = gen.get_a(new MyClass());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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