Ошибка java.lang.ClassCastException на тестовом сервере. - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь написать рекурсивную функцию, в которой я могу иметь массив любого типа, строку, int, bigdecimal, любые объекты. Поэтому я пытаюсь написать что-то вроде этого:

if(foo.getClass().isArray())
{
    Object[] objects = (Object[]) foo; //FAILS here
    //do something
}

Это проходитв коде, но это не на сервере. Получение ошибки

class [Z cannot be cast to class [Ljava.lang.Object; ([Z and [Ljava.lang.Object; 

SO, например, если есть int [], тогда он входит в цикл, но когда он пытается сделать (Object []) o, он терпит неудачу здесь.

Ответы [ 3 ]

0 голосов
/ 25 октября 2019

Если вы знаете, что что-то является массивом, но может быть примитивным массивом (например, int[]), используйте класс java.lang.reflect.Array для доступа к нему.

Например:

Object firstElement = Array.get(foo, 0);

извлечет первый элемент массива.

Существуют другие вспомогательные методы для получения элементов массива в виде примитивных типов, например, Array.getInt.


Вы не можете кратко получить Object[] от вашего Object, но вы можете тривиально превратить его в List<Object>, реализовав AbstractList:

List<Object> myReflectiveList = new AbstractList<Object>() {
  @Override public int size() { return Array.getLength(foo); }

  @Override public Object get(int index) {
    return Array.get(foo, index);
  }
};

Теперь вы можете относиться к этому как к любому (неизменяемому) List.


Вы можете многословно получить Object[], явно протестировав каждое из возможныхпримитивные типы и отступление к Object[]:

Object[] objs = new Object[Array.getLength(foo)];
if (foo.getClass().equals(int[].class)) {
  for (int i = 0; i < objs.length; ++i) {
    objs[i] = Array.getInt(foo, i);
  }
} else if (foo.getClass().equals(long[].class)) {
  // For loop, with Array.getLong
} /* etc for other primitive types */ else {
  // If it's an array but not a primitive array, you can just copy.
  System.arraycopy(foo, 0, objs, 0, objs.length);
}
0 голосов
/ 25 октября 2019

Этого можно добиться с помощью простой перегрузки (так как примитивы и массивы объектов обрабатываются по-разному:

if (foo.getClass().isArray()) {
    Object[] objects = castToObjectArray(foo);
    // do something
}

где:

/*
 * Generic cast applicable to any "Object"
 */
private static <T> Object[] castToObjectArray(T[] foo) {
    return Arrays.stream(foo).toArray();
    // OR
    // return Arrays.copyOf(foo, foo.length, Object[].class);
}

/***** Define primitives version below *******/

private static Object[] castToObjectArray(int[] foo) {
    return Arrays.stream(foo).mapToObj(x -> (Object) x).toArray();
}

// You need to define an overloaded version for all the primitive types you may use - simple copy past & change the parameter type.

Cheers!

0 голосов
/ 25 октября 2019
  1. вы не можете назначить массив примитивов, то есть int [], в массив Object []
  2. приведение массива объектов к Object [] не требуется, поскольку все классы наследуются от Objectкласс. Для уточнения этого последнего пункта см. Принцип замены Лискова
...