簡體   English   中英

僅當給定類名作為該類型的字符串時,轉換為未知類型

[英]Casting to Unknown Type When Only Given Class Name as a String of That Type

我目前擁有一個對象列表(使用Java 1.3),讓我們說我想將從list.get(i)返回的一個對象轉換為一種類型,我只知道類的名稱為String。 基本上,我如何對象o =(classname)list.get(i); 其中className是className的String變量。

我以為我可以使用(Class.forName(className))list.get(i),但是我收到了語法錯誤,聲稱我忘記了分號。

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

在Java 1.3中轉換為其他類型時使用的類的名稱是什么? 是否有一些方法可以通過類名的String參數為我提供正確的類型?

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

為此簡單:

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

足夠(而且更清潔)

如果你使用反射來獲得類的字段/方法就可以了

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

原因是要轉換的類型必須在編譯時知道,而不是在運行時(這是你想要做的)。

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

出現這種情況的一種情況是在使用遺留系統實施類型安全時。 例如,假設您有一個像Hibernate這樣的持久性系統,它提供了一個來自“finder”方法的原始結果List 將此原始List轉換為參數化類型將導致未經檢查的警告,如果List包含錯誤類型的對象, ClassCastException可能會在某些遠程相關代碼中的未指定時間引發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注釋是正確的。 在我們的審核過程中,如果沒有一些“證明”它是安全的,就會將警告作為錯誤提交。

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

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

好吧,Java是靜態類型的。 你不可能給它一個字符串,它會給你相應的靜態類型,這樣你就可以不進行投射。 即使使用泛型和Class<T>.cast ,轉換目標類型也不是由字符串給出,而是由在編譯時已知的泛型類型參數T 您必須手動轉換為正確的類型,或繼續使用最常見的類型(在您的情況下可能是對象)。

如果你做Class.forName(className) ,它會返回一個Class類型的對象,它包含有關運行時類型的信息,這樣它就可以讓你做

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

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

Object返回的引用的靜態類型。 這很重要:引用的對象的動態類型,以及指向該對象的引用的靜態類型。 對象的動態類型是可以由字符串“控制”的(通過使用Class.forName ),但是在編譯時必須執行的引用的靜態類型,這是(僅為了給出一個示例) )用於選擇相互重載的函數,不能由字符串確定。

這個問題已經回答了,但是我想補充一點,你應該有一個List,你可以保存幾種不同類型的對象(在這種情況下, 任何對象),但你顯然想要調用特定於每種不同類型的操作...

這個系列有什么意義? 你保留的實例是否有任何共同點 - 你可以將它們投入的任何常見超類型?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM