在下面的代码中,如果我将Generic实例化为:
Generic gen=new Generic(1,2);
没有类型参数,那么当我这样做时:
int a=gen.get_a();
它不起作用并给出
required:int Found:Java.Lang.Object
但ob.print()
有效。
所以当我这样做时:
int a=(Integer)gen.get_a();
然后它的工作原理。因此,当没有传递类型参数时,擦除会将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;
}
}
答案 0 :(得分:3)
在这里,正如Jon Skeet所说,你在变量声明中使用了原始类型。
5
它不起作用并给出
Generic gen=new Generic(1,2);
int a=gen.get_a();
如果在声明变量时未指定类型,则编译器无法猜测类型。
因为T不能,所以擦除用对象类型替换T. 原语,什么时候没有传递类型参数?
使用类型要求在声明中指定类。原始不是一个阶级。
required:int Found:Java.Lang.Object
将无法编译
因此,如果要使用整数值键入实例,则必须指定int primitive的包装器对象:
Generic<int> gen = new Generic<>(1);
当您使用泛型依赖于数字类型声明集合变量时,您必须注意到它。
Generic<Integer> gen = new Generic<>(1);
是Java中的根类,在您的情况下Object
不会扩展任何显式类,T
隐式地从T
派生。
因此,您在变量中使用原始类型,即可操纵对象
我想编译器认为返回的未指定Object
类型是T
最具体和兼容的类型,在您的情况下是T
。
您对集合的行为相同:在编译时,遇到Object
时,原始java.util.List
操纵Object
。
修改:
在这里,我将举一个例子来说明使用原始类型而不是声明类型,如果类中声明的类型扩展另一个类,则T
类不一定被编译器使用。与你的想法相反。
如果Object
类被声明为:
Generic
即使在变量声明中使用原始类型,public class Generic<T extends MyClass>{
...
}
也会返回get_a()
个对象,因为MyClass
的最具体且兼容的类型不是T
但是Object
。
MyClass