Как увидеть, является ли объект массивом без использования отражения?


Как я могу видеть в Java, если объект является массивом без использования отражения? И как я могу перебирать все элементы без использования отражения?

Я использую Google GWT, поэтому мне не разрешено использовать отражение : (

Я хотел бы реализовать следующие методы без использования refelection:

private boolean isArray(final Object obj) {
  //??..
}

private String toString(final Object arrayObject) {
  //??..
}

кстати: я также не хочу использовать JavaScript, чтобы я мог использовать его в средах, отличных от GWT.

4 72

4 ответа:

можно использовать Class.isArray()

public static boolean isArray(Object obj)
{
    return obj!=null && obj.getClass().isArray();
}

это работает как для объектов, так и для массивов примитивных типов.

для toString взгляните на Arrays.toString. Вам нужно будет проверить тип массива и вызвать соответствующий toString метод.

можно использовать instanceof.

JLS 15.20.2 оператор сравнения типов instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

во время выполнения, результат instanceof оператор true, если значение RelationalExpression не null и ссылка может быть брошена на ReferenceType без 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 с массивами.

см. также

можно получить доступ к каждому элементу массива по отдельности, используя следующий код:

Object o=...;
if ( o.getClass().isArray() ) {
    for(int i=0; i<Array.getLength(o); i++){
        System.out.println(Array.get(o, i));
    }
}

обратите внимание, что нет необходимости знать, что это за базовый массив, так как это будет работать для любого массива.

нет связи подтипов между массивами примитивного типа или между массивом примитивного типа и массивом ссылочного типа. Смотрите JLS 4.10.3.

поэтому следующее неверно в качестве теста, чтобы увидеть, если obj массив любых:

// INCORRECT!
public boolean isArray(final Object obj) {
    return obj instanceof Object[];
}

в частности, это не работает, если obj - это 1-D массив примитивов. (Это работает для примитивных массивов с более высокими размерами, хотя, потому что все массивы типы-это подтипы Object. Но это спорный вопрос в данном случае.)

Я использую Google GWT, поэтому мне не разрешено использовать отражение : (

лучшее решение (для isArray массив часть вопроса) зависит от того, что считается "использованием отражения".

  • если вызов obj.getClass().isArray() не считается использование отражения, то это лучшее решение.

  • в противном случае, лучший способ выяснить если объект имеет тип массива-это использовать последовательность 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) == '[';
    }