在下面的代码中,如果我将 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)
那么它的工作原理。那么,当没有传递类型参数时,擦除是否会替换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;
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,正如 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
操作。Object
T
编辑:在这里,我将给你另一个例子来说明,使用原始类型,而不是声明类型,Object
如果类中声明的类型扩展了另一个类,则编译器不一定会使用该类。与你的想法可能相反。
如果Generic
类是这样声明的:
public class Generic<T extends MyClass>{
...
}
Run Code Online (Sandbox Code Playgroud)
即使在变量声明中使用原始类型,get_a()
也会返回一个MyClass
对象,因为最具体和兼容的类型T
不是Object
but MyClass
。
Generic gen = new Generic(1);
MyClass myClass = gen.get_a(new MyClass());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3644 次 |
最近记录: |