2017-01-03 152 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

謝謝! :)明白了,今天通過這些瞭解了很多關於泛型和原始類型。 –