2009-01-26 47 views
8

我目前擁有對象列表(使用Java 1.3),假設我想要轉換從list.get(i )的類型,我只知道該類的名稱作爲一個字符串。本質上,我如何 Object o =(classname)list.get(i);其中className是一個className的String變量。我認爲我可以使用(Class.forName(className))list.get(i),但我收到了一個語法錯誤,聲稱我忘了分號。當只將類名給定爲該類型的字符串時,將其轉換爲未知類型

不幸的是,由於我使用的是Java 1.3,我無法訪問Class.cast(Object)方法。

在Java 1.3中投射到其他類型時使用的類的名稱是什麼?有沒有一些方法可以給我正確的類型,我需要類名的字符串參數?

+0

如果您升級您的Java版本,請直接訪問Java 6,因爲Java 5將在10月份成爲EOL。 : - ] – 2009-02-03 21:49:38

回答

5

不,你不能在大多數語言中這樣做。

原因是要編譯的類型在編譯時必須知道,而不是在運行時(這是您正在嘗試執行的操作)。

如果你仔細想一想,這是有道理的,因爲假設變量可以是任何類型的名稱,你應該如何訪問各種成員?你不能,除非它們是在所有實例實現的基類型/接口中定義的,在這種情況下,你應該使用它。

1

我假設你確實想寫下面的內容,而不是在左邊使用Object。除此之外,它實際上只是檢查列表中的對象是否是正確的類型。

ClassName o = (classname)list.get(i); 

那麼,Java是靜態類型的。你不可能給它一個字符串,它會給你相應的靜態類型,這樣你就不用投射了。即使使用泛型和Class<T>.cast,轉換目標類型也不是由字符串給出,而是由編譯時已知的泛型類型參數T給出。您必須手動轉換爲正確的類型,或者繼續使用最常見的類型(可能是您的案例中的Object)。

如果你這樣做Class.forName(className),它給你回,其中包含有關在運行時類型的信息,以便它可以讓你做

Class.forName("my.stuff.MyClass").newInstance() 

但劇組想要一個類型的類型Class的一個目標 - 不某種類型的對象。這就是編譯器告訴你該代碼有問題的原因。

返回的引用的靜態類型爲Object。這很重要:引用的對象的動態類型,以及指向該對象的引用的靜態類型。該對象的動態類型是可以由字符串「控制」(通過使用Class.forName),但是在編譯時必須使用的引用的靜態類型,這是(僅舉一個例子)使用的選擇相互重載的函數,不能由字符串決定。

10

當你所做的只是將結果賦值給對象時,鑄造的要點是什麼? 如果它沒有實現接口/擴展,或者是類,或者如果它沒有做任何事情,那麼您將實現的只是一個例外。

對於簡單:

public static boolean IsInstance(object x, String className) 
    { 
    Class cls = Class.forName(className); 
    return cls.isInstance(x); 
    } 

是足夠了(清潔劑)

如果你要使用反射來獲取在田/這只是罰款類的方法

+0

正是這一點---失敗很快,除了一個例外,就是問題出在哪裏,而不是某些未指定的稍後時間和地點。 – erickson 2009-01-26 20:03:54

0

問題是answered已經,但我想補充一點,你應該有一個列表,其中你保留幾種不同的對象(在這種情況下,任何對象)似乎有點可疑,但你會pparently喜歡援引他們對每種不同類型特定的操作...

這個集合有什麼意義?不要讓你保存的實例有共同的任何東西 - 你可以將它們轉換成任何常見的超類型?

2

其中需要這種情況的一種情況是在使用舊版系統執行類型安全性時。例如,假設您有像Hibernate這樣的持久性系統,它提供了來自「finder」方法的結果的原始List。將此原始List轉換爲參數化類型將導致未經檢查的警告,並且如果List包含錯誤類型的對象,則可以在某個遠程相關代碼中的某個未指定時間引發ClassCastException。使用像OP所建議的機制,最好先驗證清單的內容。

這裏的Java 1.3的版本(沒有泛型):

private static void checkType(Collection objs, String className) 
    throws ClassNotFoundException 
{ 
    Class clz = Class.forName(className); 
    Iterator i = objs.iterator(); 
    while (i.hasNext()) { 
    Object obj = i.next(); 
    if (!clz.isInstance(obj)) { 
     throw new ClassCastException(); 
    } 
    } 
} 

在Java 5及更高版本,使用泛型,你可以做的Class.cast()方法來驗證一個集合的內容類似的東西,證明使用的SuppressWarnings註釋。在我們的審查過程中,如果沒有一些「證據」證明它是安全的,那麼將其警告提交爲一個錯誤。

相關問題