Cast primitive type array dans object array en java

Pourquoi Je ne peux pas faire cela en java?

Object[] o = (Object[])(new int[]{0,1,2,3.14,4});

j'ai une méthode qui reçoit un objet et le représente ensuite comme une chaîne, mais en fonction de son type (primitif, enveloppeur primitif, tableau, etc...). Quand je créais un test D'Unité, je passais un tableau comme Objet ce qui est Ok, mais quand j'exécute moulage de cet objet dans Object [] je suis ClassCastException. Cela ne se produit qu'avec des tableaux de type primitif. Est-il de toute façon pour éviter ce problème? Si non, quelqu'un pourrait expliquer ce qui est la raison de ce comportement sur la Machine virtuelle Java.

Toute aide est très appréciée.

28
demandé sur Duncan Jones 2011-04-09 20:44:56

10 réponses

type Primitif ne peut pas être transformé de cette façon. Dans votre cas, il y a un tableau de valeurs doubles, à cause de 3.14. Cela va fonctionner:

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

Même cela fonctionne :

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);
}

UPDATE Ok, comme il a été dit, il n'y a pas de moyen direct pour lancer un tableau primitif vers un objet[]. Si vous voulez une méthode qui transforme n'importe quel tableau dans String, je peux suggérer cette façon

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));
        }
    }
}

Oui, c'est ennuyeux d'écrire une boucle pour chaque primitif type, mais il n'y a pas d'autre moyen, IMHO.

7
répondu StKiller 2011-04-09 19:03:49

en Java, les types primitifs et les types de référence sont deux mondes distincts. Ceci renvoie aux tableaux: un tableau primitif n'est pas un tableau objet, c'est pourquoi vous ne pouvez pas lancer.

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;
}

cela fonctionne toujours quand ils décident parfois d'ajouter de nouveaux types primitifs à la VM.

bien sûr, vous pourriez vouloir faire la copie toujours, non seulement dans le cas primitif, puis il obtient même plus simple:

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;
}

bien sûr, ce n'est pas de la coulée, mais conversion.

28
répondu Paŭlo Ebermann 2013-04-16 17:03:41

Ici est un simple one-liner:

Double[] objects = ArrayUtils.toObject(primitives);

Vous devez importer Apache commons-lang3:

import org.apache.commons.lang3.ArrayUtils;
26
répondu Datageek 2016-04-25 09:36:48

une autre implémentation de la fonction getArray avec une gestion flexible des types primitifs :

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;
}
2
répondu Hajo Thelen 2011-06-21 15:01:07

Initialement posté par L'OP dans la question elle-même, mais tiré ici comme une réponse séparée.


Après l'obtention de la réponse de StKiller et les autres utilisateurs J'ai été en mesure de créer une méthode générique, qui se trouve ci-dessous:

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;
}

Vous pouvez passer type de tableau dans la méthode getArray, qui reviendra Object [] sans lancer ClassCastException.

Merci encore pour tous vos réponses.

2
répondu Duncan Jones 2014-08-14 13:19:53

les types primitifs ne sont pas des objets. Il n'y a pas de solution, vous pouvez lancer n'importe quels tableaux qui contiennent des objets à Object[], mais pas les tableaux qui contiennent des types primitifs.

0
répondu Ingo 2011-04-09 16:48:51

Tu pourrais faire:

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]));
}

vous devez définir une classe où le constructeur définit le paramètre entier à un champ d'instance (dans la classe MyObject).

0
répondu Alex 2011-04-09 17:03:50

vous ne pouvez lancer qu'un objet de type dérivé, qui est manipulé et passé comme type de base. Dans la direction opposée, vous pouvez attribuer un type dérivé d'un type de base:

Object o = new String ("simple assignment");
String s = (String) o; 
Integer [] ia = new Integer [] {4, 2, 6};
Object  [] oa = ia;     

Mais primitive les ints ne sont pas des objets, ils ne peuvent donc pas être assignés à un tableau D'objets. Le Casting, cependant, ne jouerait, si possible, qu'un rôle dans la direction opposée.

0
répondu user unknown 2011-04-09 17:54:20

comme l'affiche originale l'indiquait pour la première fois dans sa question:

j'ai une méthode qui reçoit un objet et la représente comme une chaîne de caractères

bien que l'intention était de sortie Object'valeur dans un environnement, il a été à l'aide de Moulage comme un moyenne à cette fin. Par conséquent, l'expansion sur Pachello Ebermann's réponse, voici ma solution pour la plupart des objets toString() amicale.

Le principal problème étant tableaux, il transformera récursivement tout tableau X[] dans son équivalent objet de List<X>, si X est primitif ou non. Le reste est traité par chaque objet spécifique toString() si nécessaire, comme il se doit.

mise en garde Importante: on suppose qu'il n'y a pas de références circulaires!

Donné:

System.out.println(objectify(new double[][]{{65.5 * 15.9, 0}, {0.123456, 1}}))

Le résultat attendu est:

[[1041.45, 0.0], [0.123456, 1.0]]

Le la mise en œuvre:

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;
}
0
répondu Alexandre Delisle 2014-09-30 18:02:23
Foo[] fooArray = ...;
Bar[] barArray = Arrays.stream(fooArray).map(object -> (Bar) object).toArray();

en Supposant que l'objet est cessible pour le type de moulage en. Dans votre cas, vous pourriez transformer un tableau entier en tableau objet légèrement différemment car un flux entier a une façon différente de mapper des objets:

Arrays.stream(intArray).mapToObj(i -> (Object) i).toArray();
0
répondu Redmatters 2017-07-22 09:13:22