2013-05-07 154 views
12

所以我有一個可能是數組的對象。它也可以是原始的,或者是一個字符串。如果它是一個數組,它可以是幾乎任何東西的數組。將對象投射到陣列

我沒有問題搞清楚它是否是一個數組,但我似乎無法將它轉換爲任何可以迭代以獲取值的東西。

// o is an object and clazz is the class of the o 
if (clazz == Array.class) { 
      Class ofArray = o.getClass().getComponentType(); 
      String arrayType = ofArray.getName(); // 'Double' for my test case 
      //ERROR: [D cannot be cast to [Ljava.lang.Object 
      Object[] objects = (Object[]) o; 
    } 

我的背景是在紅寶石和PHP(它只會工作)和靜態打字與我的頭搞亂。有任何想法嗎?

編輯:

這引發錯誤

[D cannot be cast to [Ljava.lang.Object. 

我缺少什麼?

if (o.getClass().isArray()) { 
    Object[] objects = (Object[]) o; 
} 
+0

您可以測試一個對象以查看它是否爲數組。這個問題解決了這個問題:http://stackoverflow.com/questions/219881/java-array-reflection-isarray-vs-instanceof然後你可以安全地轉換它。 – Marvo 2013-05-07 19:52:23

+0

那麼爲什麼我的例子中的演員沒有工作? – 2013-05-07 19:55:31

+0

不確定,但可能該特定對象不是數組。 'clazz == Array.class'可能讓一些非數組對象通過。 – Marvo 2013-05-07 20:04:50

回答

19

如果你不想讓交換機的所有基本類型,你可以這樣做:

if (ofArray.isPrimitive()) { 
    int length = Array.getLength(o); 
    for (int i = 0; i < length; i++) { 
     Object obj = Array.get(o, i); 
     System.out.println(obj); 
    } 
} 
else { 
    Object[] objects = (Object[]) o; 
    for (Object obj : objects) { 
     System.out.println(obj); 
    } 
} 

編輯: 如果你不想在循環在你的代碼中使用兩個不同的地方此方法將原始數組轉換爲對象數組:

static Object[] convertToObjectArray(Object array) { 
    Class ofArray = array.getClass().getComponentType(); 
    if (ofArray.isPrimitive()) { 
     List ar = new ArrayList(); 
     int length = Array.getLength(array); 
     for (int i = 0; i < length; i++) { 
      ar.add(Array.get(array, i)); 
     } 
     return ar.toArray(); 
    } 
    else { 
     return (Object[]) array; 
    } 
} 
+1

這是有效的,但要小心:隱式裝箱操作發生在這裏:'Array.get(o,i)' - 換句話說,'int'類型的元素正被轉換爲'Integer',類型'雙'正被轉換爲'雙',等等。從長遠來看,這可能是低效的 – 2013-05-07 20:39:14

+0

是的,如果他想要效率的話,這點很好。 – Vegard 2013-05-07 20:53:15

+0

太棒了!非常感謝你 – Hartmut 2014-12-09 13:53:41

1

這將爲陣列工作與是Object sublcasses元素:

if (clazz.isArray()) { 
    Object[] objects = (Object[]) o; 
    for (Object obj : objects) 
     System.out.println(obj); 
} 

如果您需要將數組轉換到你可以(AB)使用instanceof一個特定陣列類型但,說,只需將內容打印爲字符串即可,Object[]就足夠了。

UPDATE

如果數組是原始類型的,你別無選擇,只能以測試每一個和轉換爲正確的類型,Object[]不會對這種情況下的工作 - 但也有不 Java中的很多原始類型,所以它不會是一個巨大的開關:)。這就是我的意思是:

if (clazz.isArray()) { 
    if (clazz.getComponentType().equals(double.class)) { 
     double[] numbers = (double[]) o; 
     for (double d : numbers) 
      System.out.println(d); 
    } 
} 
+0

感謝你的回覆,但它仍然無法正常工作,請查看更新後的問題。 – 2013-05-07 20:10:30

+1

錯誤發生在哪一行?上面的代碼完美地工作,問題必須在別處 – 2013-05-07 20:12:31

+0

錯誤發生在演員身上。 (第2行)我注意到,如果我將測試數組組件類型從'double'更改爲相應的包裝'Double',我不會收到錯誤。 – 2013-05-07 20:16:53

0

這是不夠的,知道你的Object是一個數組 - 你也應該知道的基本類型數組元素。如果你的數組元素是基本類型的,說double,則需要

double[] doubleArray = (double[]) o; 

這是行不通的:

Object[] objects = (Object[]) o; 
+0

是的,但我可以在不知道原始類型的情況下做到這一點嗎? (無需編寫一個巨大的開關) – 2013-05-07 20:28:38

+1

您嘗試使用Java的方式在您提到的腳本語言中很常見:php,ruby。在像Java這樣的靜態類型語言中,這個你想要的東西可能在某種程度上甚至可以被實現,但是會很慢並且不被認爲是好的編碼。 – fjf2002 2013-05-07 20:33:02

+0

您應該嘗試更一般地概述您的問題,以便我們可以爲您提供有關如何在Java中處理該問題的一般提示。使用Object類型來傳遞數組,字符串和其他類型的方法不是一個好主意。 – fjf2002 2013-05-07 20:41:38

1

你不能類型轉換原語的數組到Object[]

if (clazz == Array.class) { 
    Class ofArray = o.getClass().getComponentType(); 
    // String arrayType = ofArray.getName(); // 'Double' for my test case 
    if (ofArray instanceof double.class) 
    double[] doubles = (double[]) o; 
    for (double d: doubles) 
    System.out.println(d); 
} 

要創建一個Object[]沒有instanceof檢查

if (!(o instanceof Object[])) { 
    int len = Array.getLength(o); 
    Object[] objects = new Object[len]; 
    for (int i = 0; i < len; i++) 
    objects[i] = Array.get (o, i); 
    for (Object obj: objects) 
    System.out.println(obj); 
} 
+0

第二個版本正是我想要的!我不需要調試輸出的效率,只是簡潔! – Xerus 2017-10-29 11:41:47