# 故障排除

> 原文： [https://docs.oracle.com/javase/tutorial/reflect/special/arrayTrouble.html](https://docs.oracle.com/javase/tutorial/reflect/special/arrayTrouble.html)

以下示例显示了在阵列上操作时可能出现的典型错误。

## 由于 Inconvertible 类型导致的 IllegalArgumentException

[``ArrayTroubleAgain`` ](example/ArrayTroubleAgain.java)例子将产生 [`IllegalArgumentException`](https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalArgumentException.html) 。 [`Array.setInt()`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Array.html#setInt-java.lang.Object-int-int-) 被调用以设置具有基本类型`int`值的引用类型`Integer`的组件。在非反射等价物`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)`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Array.html#set-java.lang.Object-int-java.lang.Object-) 的以下调用：

```
Array.set(ary, 0, new Integer(1));

```

* * *

**Tip:** When using reflection to set or get an array component, the compiler does not have an opportunity to perform boxing. It can only convert types that are related as described by the specification for [`Class.isAssignableFrom()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#isAssignableFrom-java.lang.Class-). The example is expected to fail because `isAssignableFrom()` will return `false` in this test which can be used programmatically to verify whether a particular conversion is possible:

```
Integer.class.isAssignableFrom(int.class) == false 

```

类似地，在反射中也不可能从原始类型到引用类型的自动转换。

```
int.class.isAssignableFrom(Integer.class) == false

```

* * *

## 空数组的 ArrayIndexOutOfBoundsException

[``ArrayTrouble`` ](example/ArrayTrouble.java)示例说明了在尝试访问零长度数组的元素时会发生的错误：

```
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)

```

* * *

**Tip:** It is possible to have arrays with no elements (empty arrays). There are only a few cases in common code where they are seen but they can occur in reflection inadvertently. Of course, it is not possible to set/get the values of an empty array because an [`ArrayIndexOutOfBoundsException`](https://docs.oracle.com/javase/8/docs/api/java/lang/ArrayIndexOutOfBoundsException.html) will be thrown.

* * *

## 如果尝试缩小，则为 IllegalArgumentException

[``ArrayTroubleToo`` ](example/ArrayTroubleToo.java)示例包含失败的代码，因为它尝试执行可能会丢失数据的操作：

```
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)

```

* * *

**Tip:** The `Array.set*()` and `Array.get*()` methods will perform automatic widening conversion but will throw an [`IllegalArgumentException`](https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalArgumentException.html) if a narrowing conversion is attempted. For complete discussion of widening and narrowing conversions, see [_The Java Language Specification, Java SE 7 Edition_](https://docs.oracle.com/javase/specs/jls/se7/html/index.html), sections [Widening Primitive Conversion](https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.2) and [Narrowing Primitive Conversion](https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3) respectively.

* * *