Spec-Zone .ru
спецификации, руководства, описания, API
|
Следующие примеры показывают типичные ошибки, которые могут произойти, работая на массивах.
пример генерирует ArrayTroubleAgain
IllegalArgumentException
. Array.setInt()
Integer
со значением типа примитива int
. В неотражательном эквиваленте ary[0] = 1
, компилятор преобразовал бы (или поле) значение 1
к ссылочному типу как new Integer(1)
так, чтобы его проверка типа приняла оператор. При использовании отражения введите проверку, только происходит во времени выполнения, таким образом, нет никакой возможности к полю значения.
import java.lang.reflect.Array; import static java.lang.System.err; public class ArrayTroubleAgain { public static void main(String... args) { Integer[] ary = new Integer[2]; try { Array.setInt(ary, 0, 1); // IllegalArgumentException // production code should handle these exceptions more gracefully } catch (IllegalArgumentException x) { err.format("Unable to box%n"); } catch (ArrayIndexOutOfBoundsException x) { x.printStackTrace(); } } }
$ java ArrayTroubleAgain Unable to box
Чтобы устранить это исключение, проблематичная строка должна быть заменена следующим вызовом Array.set(Object array, int index, Object value)
Array.set(ary, 0, new Integer(1));
Class.isAssignableFrom()
isAssignableFrom()
возвратится false
в этом тесте, который может использоваться программно, чтобы проверить, возможно ли определенное преобразование: Integer.class.isAssignableFrom(int.class) == false
Точно так же автоматическое преобразование от примитивного до ссылочного типа также невозможно в отражении.
int.class.isAssignableFrom(Integer.class) == false
пример иллюстрирует ошибку, которая произойдет, если попытка будет предпринята, чтобы получить доступ к элементам массива нулевой длины:ArrayTrouble
import java.lang.reflect.Array; import static java.lang.System.out; public class ArrayTrouble { public static void main(String... args) { Object o = Array.newInstance(int.class, 0); int[] i = (int[])o; int[] j = new int[0]; out.format("i.length = %d, j.length = %d, args.length = %d%n", i.length, j.length, args.length); Array.getInt(o, 0); // ArrayIndexOutOfBoundsException } }
$ java ArrayTrouble i.length = 0, j.length = 0, args.length = 0 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException at java.lang.reflect.Array.getInt(Native Method) at ArrayTrouble.main(ArrayTrouble.java:11)
ArrayIndexOutOfBoundsException
будет брошен.
пример содержит код, который перестал работать, потому что это пытается, выполняют работу, которая могла потенциально потерять данные:ArrayTroubleToo
import java.lang.reflect.Array; import static java.lang.System.out; public class ArrayTroubleToo { public static void main(String... args) { Object o = new int[2]; Array.setShort(o, 0, (short)2); // widening, succeeds Array.setLong(o, 1, 2L); // narrowing, fails } }
$ java ArrayTroubleToo Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch at java.lang.reflect.Array.setLong(Native Method) at ArrayTroubleToo.main(ArrayTroubleToo.java:9)
Array.set*()
и Array.get*()
методы выполнят автоматическое расширяющееся преобразование, но бросят IllegalArgumentException
если сужающееся преобразование предпринимается. Для полного обсуждения расширения и сужения преобразований, см.