2017-06-05 54 views
0

我學習Java的泛型:https://docs.oracle.com/javase/tutorial/java/generics/bounded.html,我有下面的代碼示例有些疑惑:的Java泛型的理解型

public class Box<T> { 

    private T t;   

    public void set(T t) { 
     this.t = t; 
    } 

    public T get() { 
     return t; 
    } 

    public <U extends Number> void inspect(U u) { 
     System.out.println("T: " + t.getClass().getName()); 
     System.out.println("U: " + u.getClass().getName()); 
    } 

    public static void main(String[] args) { 
     Box<Integer> integerBox = new Box<Integer>(); 
     integerBox.set(new Integer(10)); 
     integerBox.inspect("some text"); // error: this is still String! 
    } 
} 

爲什麼wasnt的檢查()寫入方法,如下圖所示,而不是它是什麼?

public <T extends Number> void inspect(T t) { } 

還有一些其他代碼示例具有以下語法。第一對代表什麼?

public <K,V> SomeClass<K,V> 

靜態代表什麼?

public static <T> int countGreaterThan(T[] anArray, T elem) 
+0

你的榜樣'公共 SomeClass的'應該寫成'公共類SomeClass的':) – freedev

+0

'爲什麼waspect的inspect()方法寫成如下所示,而不是它的原因?'同樣爲什麼你不能有兩個同名的字段:因爲'T'已經用於別的東西了。 – biziclop

回答

2

方法Box.inspect()期望延伸Number類型所以當參數爲String它是不適用的。

Box.inspect()只是應用於方法的泛型類型的一個示例。

在另一方面,你有一個類Box與通用類型T,但也可以有一個不接受另一類型U它是更廣泛的(上界)比T的方法。

該課程本身並沒有說如何使用inspect以及爲什麼它只是給你處理不同類型的可能性。不要對這個樣本寄予厚望。

考慮一下,它只是一個解釋如何使用泛型的示例(不是很棒的邏輯)。

關於public class SomeClass<K,V>聲明,這是一個具有多種泛型類型的聲明。

HashMap<K,V>()這個類是這種情況的一個實例,K是鍵值的類型,V是值的類型。

+0

是的我明白這是一個字符串。但是,爲什麼U擴展數字?我可以將它重命名爲T擴展數字嗎? – youcanlearnanything

+0

@ youcancanlearnanything你可以。 – freedev

+0

但SomeClass 前面的代表什麼?因爲SomeClass 代表關鍵和價值。 – youcanlearnanything

-1

是的。 Freedev答案是正確的。 嘗試

public static void main(String[] args) { 
    Test1<Integer> integerBox = new Test1<Integer>(); 
    integerBox.set(new Integer(10)); 
    integerBox.inspect(78); // inspect method expect a interger value 
} 
0
public <U extends Number> void inspect(U u) { 

等待的參數是數字類型的或派生的它。
所以你當然不能傳遞一個字符串值:

integerBox.inspect("some text"); // error: this is still String! 

在你的類中,聲明瞭兩個參數化類型:

  • 一個類聲明:public class Box<T> {

  • 另一個在public <U extends Number> void inspect(U u)方法。

這些設置了兩個不同的約束條件。

在聲明箱的實例,該整數作爲泛型類型:

Box<Integer> integerBox = new Box<>(); 

使用T型這下面的字段將關聯到一個整數類型:

private T t;   

public <U extends Number> void inspect(U u)方法不使用T 類型。
所以,你可以在兩種情況下使用不同的類型:

Box<Integer> integerBox = new Box<Integer>(); 
    integerBox.set(new Integer(10)); 
    integerBox.inspect(Float.valueOf(10)); // I pass a float and it is valid. 

如果將宣佈這樣的方法:

public <T extends Number> void inspect(T t) { } 

你就必須在聲明的方法相同的行爲T會是班級中聲明的另一個T類型。
但是,這種方法是誤導性的,因爲您使用兩次相同的類型名稱(T),而這些是不同的類型。

否則,要將方法的參數限制爲在類中聲明的類型,則不必聲明靜態類型。

這是不夠的:

public void inspect(T t) { } 

現在你只能在兩種情況下使用相同類型:

Box<Integer> integerBox = new Box<Integer>(); 
    integerBox.set(new Integer(10)); 
    integerBox.inspect(Float.valueOf(10)); // doesn't compile