没有类型参数的 Java 泛型类实例化

Dee*_*osh 5 java generics

在下面的代码中,如果我将 Generic 实例化为:

Generic gen=new Generic(1,2);
Run Code Online (Sandbox Code Playgroud)

那是没有类型参数,然后当我这样做时:

int a=gen.get_a();
Run Code Online (Sandbox Code Playgroud)

它不起作用并给出

要求:int 发现:Java.Lang.Object

ob.print()有效。所以当我这样做时:

int a=(Integer)gen.get_a();
Run Code Online (Sandbox Code Playgroud)

那么它的工作原理。那么,当没有传递类型参数时,擦除是否会替换TObject类型,因为T不能是原始类型?

public class Generic<T>
{
    T a;
    Generic(T a)
    {
        this.a=a;
    }
    void print()
    {
        System.out.print(a);
    }

    T get_a()
    {
        return a;
    }
}
Run Code Online (Sandbox Code Playgroud)

dav*_*xxx 6

在这里,正如 Jon Skeet 所说,您在变量声明中使用原始类型。

 Generic gen=new Generic(1,2);
 int a=gen.get_a();
Run Code Online (Sandbox Code Playgroud)

它不起作用并给出

required:int Found:Java.Lang.Object
Run Code Online (Sandbox Code Playgroud)

如果您在声明变量时未指定类型,则编译器无法猜测类型。

那么,当没有传递类型参数时,擦除是否将 T 替换为对象类型,因为 T 不能是原始类型?

使用类型需要在声明中指定类。原始类型不是类。 Generic<int> gen = new Generic<>(1);不会编译

因此,如果您想使用整数值键入实例,则必须指定 int 原语的包装对象: Generic<Integer> gen = new Generic<>(1);
当您使用依赖于数字类型的泛型声明集合变量时,您一定已经注意到了这一点。

Object是Java中的根类,就像您的情况一样,它T不扩展任何显式类,T而是Object隐式派生的。
因此,如果您在变量中使用原始类型,则可以操作对象。
我认为编译器认为未指定的返回类型T是最具体和最兼容的类型T,在您的情况下它是Object
您对集合具有相同的行为:在编译时,遇到原始操作时会进行java.util.List操作。ObjectT


编辑:在这里,我将给你另一个例子来说明,使用原始类型,而不是声明类型,Object如果类中声明的类型扩展了另一个类,则编译器不一定会使用该类。与你的想法可能相反。

如果Generic类是这样声明的:

public class Generic<T extends MyClass>{
...
}
Run Code Online (Sandbox Code Playgroud)

即使在变量声明中使用原始类型,get_a()也会返回一个MyClass对象,因为最具体和兼容的类型T不是Objectbut MyClass

 Generic gen = new Generic(1);
 MyClass myClass = gen.get_a(new MyClass());
Run Code Online (Sandbox Code Playgroud)