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

在java中将基元类型数组强制转换为对象数组,java,arrays,casting,primitive,Java,Arrays,Casting,Primitive,为什么我不能在java中这样做 Object[] o = (Object[])(new int[]{0,1,2,3.14,4}); 我有一个方法,它接收一个对象,然后将其表示为字符串,但这取决于他的类型(基元、基元包装器、数组等)。当我创建一个单元测试时,我通过了一个数组,名为Object,这是可以的,但是当我将该对象强制转换为Object[]时,我得到了ClassCastException。 这仅在基元类型数组中发生。有没有办法避免这种行为?如果不是,有人能解释一下Java虚拟机上出现这种行

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

Object[] o = (Object[])(new int[]{0,1,2,3.14,4});
我有一个方法,它接收一个对象,然后将其表示为字符串,但这取决于他的类型(基元、基元包装器、数组等)。当我创建一个单元测试时,我通过了一个数组,名为Object,这是可以的,但是当我将该对象强制转换为Object[]时,我得到了ClassCastException。 这仅在基元类型数组中发生。有没有办法避免这种行为?如果不是,有人能解释一下Java虚拟机上出现这种行为的原因吗


非常感谢您的帮助。

基本类型不是对象。没有解决方法,您可以将任何包含对象的数组强制转换为Object[],但不能将包含基元类型的数组强制转换为Object[]

int[] intArray = new int[]{0,1,2,3,14,4};
ArrayList<MyObject> myObjArray = new ArrayList<MyObject>;

for (int i = 0; i < intArray.length; i++) {
myObjArray.set(new MyObject(intArray[i]));
}
int[]intArray=newint[]{0,1,2,3,14,4};
ArrayList myObjArray=新的ArrayList;
for(int i=0;i

您需要定义一个类,其中构造函数将整型参数设置为实例字段(在MyObject类中)。

原语类型不能以这种方式转换。 在您的例子中,有一个双值数组,原因是3.14。 这将有助于:

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

是的,为每个基元类型编写循环是很烦人的,但是没有其他方法,IMHO

只能强制转换派生类型的对象,该类型作为基类型处理和传递。相反,您可以将派生类型指定给基类型:

Object o = new String ("simple assignment");
String s = (String) o; 
物体并没有发生任何变化——它只是被伪装成它是什么,它一直是什么

Integer [] ia = new Integer [] {4, 2, 6};
Object  [] oa = ia;     

但是基元整数不是对象,因此不能将它们指定给对象数组。但是,如果可能的话,强制转换只会起到相反的作用。

在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;
}
private Object[]getArray(Object val){
if(对象[]的val instanceof)
返回(Object[])val;
int arrlength=Array.getLength(val);
Object[]outputArray=新对象[arrlength];
对于(int i=0;i
当他们有时决定向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;
}
private Object[]getArray(Object val){
int arrlength=Array.getLength(val);
Object[]outputArray=新对象[arrlength];
对于(int i=0;i

当然,这不是强制转换,而是转换getArray函数的另一个实现,它可以灵活处理基元类型:

public static Object[] createArrayFromArrayObject(Object o) throws XYZException {
    if(!o.getClass().isArray())
        throw new XYZException("parameter is not an array");

    if(!o.getClass().getComponentType().isPrimitive())
        return (Object[])o;

    int element_count = Array.getLength(o);
    Object elements[] = new Object[element_count];

    for(int i = 0; i < element_count; i++){
        elements[i] = Array.get(o, i);          
    }

    return elements;
}
public静态对象[]createArrayFromArrayObject(对象o)抛出XYZEException{
如果(!o.getClass().isArray())
抛出新的XYZException(“参数不是数组”);
如果(!o.getClass().getComponentType().isPrimitive())
返回(对象[])o;
int element_count=Array.getLength(o);
对象元素[]=新对象[元素计数];
对于(int i=0;i
最初由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;
}
private final Class[]ARRAY\u PRIMITIVE\u TYPES={
int[].class、float[].class、double[].class、boolean[].class、,
字节[].class,短[].class,长[].class,字符[].class};
私有对象[]getArray(对象值){
类valKlass=val.getClass();
对象[]输出阵列=null;
for(类arrKlass:ARRAY\u PRIMITIVE\u类型){
if(valKlass.isAssignableFrom(arrKlass)){
int arrlength=Array.getLength(val);
outputArray=新对象[arrlength];
对于(int i=0;i
您可以将类数组传递到getArray方法中,该方法将返回对象[],而不会抛出ClassCastException


再次感谢您的回复。

正如原始海报在其问题中首先指出的那样:

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;
}
我有一个方法,它接收一个对象,然后将其表示为字符串

虽然目的是以友好的方式输出
对象的值,但他使用了施法作为实现这一目的的手段。因此,根据帕罗·埃伯曼的回答,下面是我的解决方案,使大多数对象对字符串()友好

主要的问题是数组,它将递归地将任何数组
X[]
转换为它的对象等价物
List
,无论
X
是否为基元。其余部分由每个特定对象的
toString()
处理(如果需要)

重要注意事项:假定没有循环引用

给定的

System.out.println(objectify(new double[][]{{65.5 * 15.9, 0}, {0.123456, 1}}))
[[1041.45, 0.0], [0.123456, 1.0]]
public Object objectify(Object obj) {
    if(obj == null)
        return obj;
    Object o = obj;
    if(obj.getClass().isArray()) {
        // array
        if(obj instanceof Object[]) {
            // array of Object
            Object[] oI = (Object[])obj;
            Object[] oO = new Object[oI.length];
            for(int i = 0; i < oI.length; i++) {
                // objectify elements
                oO[i] = objectify(oI[i]);
            }
            o = Arrays.asList(oO);
        } else {
            // array of primitive
            int len = Array.getLength(obj);
            Object[] out = new Object[len];
            for(int i = 0; i < len; i++)
                out[i] = Array.get(obj, i);
            o = Arrays.asList(out);
        }
    }
    return o;
}
预期结果为

System.out.println(objectify(new double[][]{{65.5 * 15.9, 0}, {0.123456, 1}}))
[[1041.45, 0.0], [0.123456, 1.0]]
public Object objectify(Object obj) {
    if(obj == null)
        return obj;
    Object o = obj;
    if(obj.getClass().isArray()) {
        // array
        if(obj instanceof Object[]) {
            // array of Object
            Object[] oI = (Object[])obj;
            Object[] oO = new Object[oI.length];
            for(int i = 0; i < oI.length; i++) {
                // objectify elements
                oO[i] = objectify(oI[i]);
            }
            o = Arrays.asList(oO);
        } else {
            // array of primitive
            int len = Array.getLength(obj);
            Object[] out = new Object[len];
            for(int i = 0; i < len; i++)
                out[i] = Array.get(obj, i);
            o = Arrays.asList(out);
        }
    }
    return o;
}
实施

System.out.println(objectify(new double[][]{{65.5 * 15.9, 0}, {0.123456, 1}}))
[[1041.45, 0.0], [0.123456, 1.0]]
public Object objectify(Object obj) {
    if(obj == null)
        return obj;
    Object o = obj;
    if(obj.getClass().isArray()) {
        // array
        if(obj instanceof Object[]) {
            // array of Object
            Object[] oI = (Object[])obj;
            Object[] oO = new Object[oI.length];
            for(int i = 0; i < oI.length; i++) {
                // objectify elements
                oO[i] = objectify(oI[i]);
            }
            o = Arrays.asList(oO);
        } else {
            // array of primitive
            int len = Array.getLength(obj);
            Object[] out = new Object[len];
            for(int i = 0; i < len; i++)
                out[i] = Array.get(obj, i);
            o = Arrays.asList(out);
        }
    }
    return o;
}
public objectify(Object obj){
if(obj==null)
返回obj;
对象o=对象j;
if(obj.getClass().isArray()){
//排列
if(对象[]的obj实例){
//对象数组
对象[]o
public static void main(String[] args) {
    final int size1 = 5;
    final int size2 = 4;
    int[][] b = new int[size1][size2];
    for (int i = 0; i < size1; i++)
        for (int j = 0; j < size2; j++)
            b[i][j] = (i + 1) * (j + 1);
    b[1] = new int[7];
    b[1][4] = 4;
    b[3] = null;
    System.out.println(b.getClass().getCanonicalName());
    System.out.println(Arrays.deepToString(b));
    Integer[][] w = (Integer[][])wrap(b);
    System.out.println(w.getClass().getCanonicalName());
    System.out.println(Arrays.deepToString(w));
}