2017-01-03 258 views
1

在下面的代码,如果我实例一般为:Java的泛型类实例化没有类型参数

Generic gen=new Generic(1,2); 

是没有类型参数,然后当我做到这一点:

int a=gen.get_a(); 

它不工作,给

要求:诚信部发现:java.lang.Object继承

ob.print()的作品。 所以,当我这样做,而不是:

int a=(Integer)gen.get_a(); 

然后它工作。那么删除替换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; 
    } 
} 
+2

基本上你使用的是原始类型。请参阅http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html#Raw Types –

+0

谢谢!我现在明白了 –

回答

2

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

Generic gen=new Generic(1,2); 
int a=gen.get_a(); 

它不工作,给

required:int Found:Java.Lang.Object 

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

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

在声明中使用类型需求指定类。而一个原始人不是一个阶级。 Generic<int> gen = new Generic<>(1);不会编译

所以,你必须指定,如果你想用一个整数值,输入您的实例INT原始的包装对象: Generic<Integer> gen = new Generic<>(1);
必须做好注意到了这一点,当你宣布一个集合变量泛型依赖于数字类型。

Object是Java中的根类,因为在你的情况下,T没有扩展任何显式类,T隐含地从Object派生。
因此,它使用变量中的原始类型来处理对象。
我想编译器认为返回类型的未指定TT的最具体和兼容的类型,在你的情况下它是Object
您对集合具有相同的行为:在编译时,遇到T时,原始java.util.List操纵Object


编辑: 在这里,我给你举个例子来说明,与原始的类型,而不是申报类型,Object类不一定是由编译器使用,如果在类中声明的类型扩展另一类。与你想象的相反。

如果Generic类被宣布这样的:

public class Generic<T extends MyClass>{ 
... 
} 

即使采用在变量的声明中的原始类型,get_a()将返回MyClass对象,因为对于T最具体和兼容的类型不是Object,但MyClass

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

谢谢。我现在知道了,在我的代码中,如果我添加了它说 找到了:Java.Lang.Number 如您在示例中所示。谢谢!! :) 另一个问题让我吃惊,如果我说: LinkedList list = new LinkedList <>(); List l = list; 这是行不通的,我知道,但假设是 列表l_interface =列表 这个工作,是l_interface也是一个raw类型,意思是l_interface也会隐式地派生object ?? I –

+0

欢迎您:)'列表l_interface'声明是任何东西的列表。所以编译器用最普通的类型替换泛型:'Object'。 当你写'LinkedList list = ...;列表l_interface = list',您将使用泛型的列表对象分配给原始列表。编译器不会阻止你这样做,但它警告你(带有警告),并且你失去了通用机制,因为这个列表是对象列表。 – davidxxx

+0

谢谢! :)明白了,今天通过这些了解了很多关于泛型和原始类型。 –