在java中将基元类型数组转换为对象数组

aum*_*ets 31 java arrays primitive casting

为什么我不能在java中这样做?

Object[] o = (Object[])(new int[]{0,1,2,3.14,4});
Run Code Online (Sandbox Code Playgroud)

我有一个方法接收一个对象,然后将其表示为一个字符串,但取决于他的类型(原始,原始包装,数组等).当我创建一个Unit测试时,我将一个数组作为Object传递,这是好的,但当我执行该对象的转换为Object []时,我得到了ClassCastException.这只发生在原始类型数组中.有什么方法可以避免这种行为吗?如果没有,有人可以解释在Java虚拟机上这种行为的原因是什么.

非常感谢任何帮助.

Dat*_*eek 32

这是一个简单的单行:

Double[] objects = ArrayUtils.toObject(primitives);
Run Code Online (Sandbox Code Playgroud)

您将需要导入Apache commons-lang3:

import org.apache.commons.lang3.ArrayUtils;
Run Code Online (Sandbox Code Playgroud)


Paŭ*_*ann 30

在Java中,原始类型和引用类型是两个截然不同的世界.这反映了数组:原始数组不是对象数组,这就是你无法转换的原因.

以下是问题中解决方案的简单版本:

private Object[] getArray(Object val){
    if (val instanceof Object[])
       return (Object[])val;
    int arrlength = Array.getLength(val);
    Object[] outputArray = new Object[arrlength];
    for(int i = 0; i < arrlength; ++i){
       outputArray[i] = Array.get(val, i);
    }
    return outputArray;
}
Run Code Online (Sandbox Code Playgroud)

当它们有时决定向VM添加新的基元类型时,它仍然有效.

当然,您可能希望始终进行复制,不仅在原始情况下,它甚至更简单:

private Object[] getArray(Object val){
    int arrlength = Array.getLength(val);
    Object[] outputArray = new Object[arrlength];
    for(int i = 0; i < arrlength; ++i){
       outputArray[i] = Array.get(val, i);
    }
    return outputArray;
}
Run Code Online (Sandbox Code Playgroud)

当然,这不是铸造,而是转换.

  • “ Array.getLength”和“ get”正是我所需要的。比检查数组是否为给定的原始类型然后将其强制转换为更干净的代码。谢谢! (2认同)

StK*_*ler 7

原始类型不能以这种方式转换.在您的情况下,有一个double值数组,原因是3.14.这将有效:

    List<Object> objectList = new ArrayList<Object>();
    objectList.addAll(Arrays.asList(0,1,2,3.14,4));
Run Code Online (Sandbox Code Playgroud)

即便如此:

List<Object> objectList = new ArrayList<Object>();
objectList.addAll(Arrays.asList(0,"sfsd",2,3.14,new Regexp("Test")));
for(Object object:objectList)
{
    System.out.println(object);
}
Run Code Online (Sandbox Code Playgroud)

UPDATE 好的,就像那里所说的那样,没有直接的方法将原始数组转换为Object [].如果你想要一个转换String中任何数组的方法,我可以这样建议

public class CastArray {

    public static void main(String[] args) {
        CastArray test = new CastArray();
        test.TestObj(new int[]{1, 2, 4});
        test.TestObj(new char[]{'c', 'a', 'a'});
        test.TestObj(new String[]{"fdsa", "fdafds"});
    }

    public void TestObj(Object obj) {
        if (!(obj instanceof Object[])) {
            if (obj instanceof int[]) {
                for (int i : (int[]) obj) {
                    System.out.print(i + " ");
                }
                System.out.println("");
            }
            if (obj instanceof char[]) {
                for (char c : (char[]) obj) {
                    System.out.print(c + " ");
                }
                System.out.println("");
            }
            //and so on, for every primitive type.
        } else {
            System.out.println(Arrays.asList((Object[]) obj));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

是的,为每种原始类型编写一个循环很烦人,但没有其他办法,恕我直言.


Dun*_*nes 6

最初由 OP 在问题本身中发布,但作为单独的答案拉到这里。


在得到 StKiller 和其他用户的响应后, 我能够创建一个更通用的方法,它位于下面:

private final Class<?>[] ARRAY_PRIMITIVE_TYPES = { 
        int[].class, float[].class, double[].class, boolean[].class, 
        byte[].class, short[].class, long[].class, char[].class };

private Object[] getArray(Object val){
    Class<?> valKlass = val.getClass();
    Object[] outputArray = null;

    for(Class<?> arrKlass : ARRAY_PRIMITIVE_TYPES){
        if(valKlass.isAssignableFrom(arrKlass)){
            int arrlength = Array.getLength(val);
            outputArray = new Object[arrlength];
            for(int i = 0; i < arrlength; ++i){
                outputArray[i] = Array.get(val, i);
                            }
            break;
        }
    }
    if(outputArray == null) // not primitive type array
        outputArray = (Object[])val;

    return outputArray;
}
Run Code Online (Sandbox Code Playgroud)

您可以将数组类型传递给 getArray 方法,该方法将返回Object[]而不抛出 ClassCastException。

再次感谢您的所有回复。