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.
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.
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.
Ici est un simple one-liner:
Double[] objects = ArrayUtils.toObject(primitives);
Vous devez importer Apache commons-lang3:
import org.apache.commons.lang3.ArrayUtils;
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;
}
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.
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.
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).
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.
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;
}
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();