Как определить, является ли объект массивом без использования отражения?
Как я могу видеть на Java, если объект представляет собой массив без использования отражения?
И как я могу перебирать все элементы без отражения?
Я использую Google GWT, поэтому мне не разрешено использовать рефлексию: (
Мне бы хотелось реализовать следующие методы без использования refelection:
private boolean isArray(final Object obj) {
//??..
}
private String toString(final Object arrayObject) {
//??..
}
Кстати: и я не хочу использовать JavaScript, чтобы я мог использовать его в средах без GWT.
Ответы
Ответ 1
Вы можете использовать Class.isArray()
public static boolean isArray(Object obj)
{
return obj!=null && obj.getClass().isArray();
}
Это работает как для массивов объектов, так и для примитивных типов.
Для toString взгляните на Arrays.toString
. Вам нужно будет проверить тип массива и вызвать соответствующий метод toString
.
Ответ 2
Вы можете использовать instanceof
.
RelationalExpression:
RelationalExpression instanceof ReferenceType
Во время выполнения результат оператора instanceof
равен true
, если значение RelationalExpression не равно null
, и ссылка может быть передана в ReferenceType без повышения a ClassCastException
. В противном случае результат false
.
Это означает, что вы можете сделать что-то вроде этого:
Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"
Вам нужно будет проверить, есть ли объект instanceof boolean[]
, byte[]
, short[]
, char[]
, int[]
, long[]
, float[]
, double[]
или Object[]
, если вы хотите определить все типы массивов.
Кроме того, int[][]
является instanceof Object[]
, поэтому в зависимости от того, как вы хотите обрабатывать вложенные массивы, он может усложняться.
Для toString
java.util.Arrays
имеет toString(int[])
и другие перегрузки, которые вы можете использовать. Он также имеет deepToString(Object[])
для вложенных массивов.
public String toString(Object arr) {
if (arr instanceof int[]) {
return Arrays.toString((int[]) arr);
} else //...
}
Это будет очень повторяющимся (но даже java.util.Arrays
очень повторяется), но так, как в Java с массивами.
См. также
Ответ 3
Можно получить доступ к каждому элементу массива отдельно, используя следующий код:
Object o=...;
if ( o.getClass().isArray() ) {
for(int i=0; i<Array.getLength(o); i++){
System.out.println(Array.get(o, i));
}
}
Обратите внимание, что нет необходимости знать, какой он базовый массив, поскольку это будет работать для любого массива.
Ответ 4
Не существует отношения подтипов между массивами примитивного типа или между массивом примитивного типа и массивом ссылочного типа. См. JLS 4.10.3.
Поэтому в качестве теста ниже показано, является ли obj
массивом любого вида:
// INCORRECT!
public boolean isArray(final Object obj) {
return obj instanceof Object[];
}
В частности, он не работает, если obj
является одномерным массивом примитивов. (Это работает для примитивных массивов с более высокими измерениями, потому что все типы массивов являются подтипами Object
. Но в данном случае это спорный вопрос.)
Я использую Google GWT, поэтому мне запрещено использовать отражение :(
Лучшее решение (часть вопроса о массиве isArray
) зависит от того, что считать "использованием отражения".
-
В GWT вызов obj.getClass().isArray()
не считается использованием отражения 1 так что это лучшее решение.
-
В противном случае лучший способ выяснить, имеет ли объект тип массива, - это использовать последовательность выражений instanceof
.
public boolean isArray(final Object obj) {
return obj instanceof Object[] || obj instanceof boolean[] ||
obj instanceof byte[] || obj instanceof short[] ||
obj instanceof char[] || obj instanceof int[] ||
obj instanceof long[] || obj instanceof float[] ||
obj instanceof double[];
}
-
Вы также можете попробовать поиграть с именем класса объекта следующим образом, но вызов obj.getClass()
граничит с отражением.
public boolean isArray(final Object obj) {
return obj.getClass().toString().charAt(0) == '[';
}
1 - Точнее, метод Class.isArray
указан как поддерживаемый GWT на этой странице.
Ответ 5
Вы можете создать служебный класс, чтобы проверить, представляет ли класс какую-либо коллекцию, карту или массив
public static boolean isCollection(Class<?> rawPropertyType) {
return Collection.class.isAssignableFrom(rawPropertyType) ||
Map.class.isAssignableFrom(rawPropertyType) ||
rawPropertyType.isArray();
}