2010-01-29 40 views
-1

因爲我們知道我們可以在列表中添加字符串和整數,如果我們聲明列表的通用類型。但代碼似乎並沒有加上字符串。有什麼問題我不明白..爲什麼不能在列表中添加字符串?

class GHJ{String s;GHJ(String s){this.s=s;}} 

class DFR{ 
    public static void main(String[] g){ 
     List<? extends Object> list=new ArrayList(); 
     list.add((new String("ffg")));// compiler error 
     list.add("df");// compiler error 
     list.add("sdd");// compiler error 
     list.add(new GHJ("dff"));// compiler error 
     String s= list.get(0);// compiler error 
     System.out.println(list+" "+s); 
    } 
} 
+0

你是什麼意思'不添加字符串'你期望這個代碼做什麼? – 2010-01-29 08:37:08

+0

我們曾經這樣做:) – 2010-01-29 11:04:21

回答

0

您需要從對象投你的字符串,像這樣:

String s = (String)list.get(0); 
5

正確的方法是使用泛型。

創建列表,如:

List<String> list = new ArrayList<String>(); 

那麼你不需要投。

編輯:

由於DPB指出的是有多種類型的對象。從我的觀點來看,在列表中混合不同類型的對象需要問題。解決它的唯一辦法是:

  • 不要使用仿製藥,一切都將在列表中
  • 當你需要找回一些對象需要做這樣的事情:

    if (list.get(0) instanceof String) { 
    } else if (list.get(0) instanceof GHJ) { 
    } ..... 
    
+0

在這個例子中還有這樣的代碼:list.add(new GHJ(「dff」));.這不是一個字符串,所以你不能將它添加你的列表示例 – 2010-01-29 08:31:54

0

爲什麼會加上字符串? 它不會編譯,因爲需要投:

String str = (String)list.get(0); 
2

你告訴編譯器,在列表中的類型是什麼,擴展對象。那麼你將這些東西添加到列表中,然後試着拿出一個。所有編譯器都可以知道你得到的東西會擴展對象,而不是它肯定是一個字符串。你需要告訴編譯器你從列表中獲得一個字符串。

,如果你說

Object a= new String("blah"); 
String s; 

你需要投下一個字符串分配給它送

s= (String) a; 

什麼在你的例子發生,如果你這樣做

String s = list.get(3); 

你已經把你的new GHJ("dff")

編譯器如何知道每個位置的對象類型?

3

就你而言,你不需要使你的列表變得通用。只需使用

List list = new ArrayList(); 

這將創建Object類型的列表。

2

可以,但只能通過或者使用一個無類型(擺脫

<? super String> 

完全,所以:

List x = new List(); x.add(new Object()); x.add("blah!"); 

或找到一個共同的超類(在這種情況下,僅對象)通用參數

List<Object> x = new List<Object>(); x.add(new Object()); x.add("blah!"); 

你可以拉招數來的東西元素融入名單,繞過通用typechecks,但這是非常糟糕的Juju。

+0

是的我知道我可以添加對象和字符串使用無類型List.But我想從對象獲取值(無論是字符串或int等)。 – arindam 2010-01-29 08:57:44

+3

你無法繞過投射結果。 – PSpeed 2010-01-29 09:04:26

2

listList<? super String>型的,所以如果你想添加的東西給它,然後它需要無論是String或東西是的String一個超類。 String的唯一超類是ObjectGHJ不是String的超類,因此您無法將GHJ的實例添加到該列表。

0

這張通配符卡會把你搞亂,因爲它沒有做你打算做的事。當您需要參考某些通用泛型時,通常會使用通配符。

例如,如果您想讓用戶爲您提供包含任何類型對象的集合,那麼您的方法可能需要一個Collection<? extends Object>作爲其參數。你會想這樣做,因爲如果你只是使用Collection<Object>作爲參數,那麼他們無法通過Collection<String>

所以,問題在於List<? extends Object>有一些限制,因爲編譯器無法知道該列表需要什麼特定類型。例如,它可能是一個List<String> ......編譯器不知道。出於這個原因,你永遠無法調用任何以<? extends Object>作爲參數的List上的方法。換句話說,你不能調用add()。

你可以調用get()...因爲編譯器知道接收變量是什麼類型,並且可以檢查它是否正常。對象foo = myList.get(0)很好。

我認爲在這種情況下,你真的想要List<Object>,並確保在ArrayList上聲明類型參數。

List<Object> list = new ArrayList<Object>(); 

如果你想要字符串,那麼你將不得不專門將對象轉換爲字符串。我個人建議String.valueOf()。順便說一下,上面的內容在覈心Java第1卷(以及至少我的古老的JDK 1.5版本)的泛型章節的通配符部分有很好的記錄。

2

如果你添加不同的類型到列表中,你必須告訴編譯器你從列表中獲得哪種類型,你無法解決這個問題。

難道你不能爲每種類型的對象保留單獨的列表,也許保留一個包含各種類型列表的地圖?那麼你可以通過類型獲得每個列表,並且列表中的所有元素將是相同的類型?

1

是的,你可以在列表中添加一個列表和一個對象,但唯一的辦法是有一個無類型的列表。在這種情況下,您會丟失類型信息,並且必須手動將您從列表中移出的對象轉換回其原始類型。

你可以使用instanceof檢查到哪種類型,你可以投的對象,但這是特別難看......

的問題是:你真的需要把兩個字符串和對象在同一個列表?這看起來像一個代碼味道給我。

相關問題