2013-05-07 111 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