可以通过方法Class.isArray()
来确定一个类型是否是数组类型:
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import static java.lang.System.out;
public class ArrayFind {
public static void main(String... args) {
boolean found = false;
try {
Class<?> cls = Class.forName(args[0]);
Field[] flds = cls.getDeclaredFields();
for (Field f : flds) {
Class<?> c = f.getType();
if (c.isArray()) {
found = true;
out.format("%s%n"
+ " Field: %s%n"
+ " Type: %s%n"
+ " Component Type: %s%n",
f, f.getName(), c, c.getComponentType());
}
}
if (!found) {
out.format("No array fields%n");
}
// production code should handle this exception more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
}
}
}
运行结果:
$java ArrayFind java.nio.ByteBuffer
final byte[] java.nio.ByteBuffer.hb
Field: hb
Type: class [B
Component Type: byte
$ java ArrayFind java.lang.Throwable
private java.lang.StackTraceElement[] java.lang.Throwable.stackTrace
Field: stackTrace
Type: class [Ljava.lang.StackTraceElement;
Component Type: class java.lang.StackTraceElement
$ java ArrayFind java.awt.Cursor
protected static java.awt.Cursor[] java.awt.Cursor.predefined
Field: predefined
Type: class [Ljava.awt.Cursor;
Component Type: class java.awt.Cursor
static final java.lang.String[][] java.awt.Cursor.cursorProperties
Field: cursorProperties
Type: class [[Ljava.lang.String;
Component Type: class [Ljava.lang.String;
‘[‘的个数表示的数组的维度,getComponentType()获取的是其组成元素的类型。
通过java.lang.reflect.Array.newInstance()可以创建动态创建数组。
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Arrays;
import static java.lang.System.out;
public class ArrayCreator {
private static String s = "java.math.BigInteger bi[] = { 123, 234, 345 }";
private static Pattern p = Pattern.compile("^\\s*(\\S+)\\s*\\w+\\[\\].*\\{\\s*([^}]+)\\s*\\}");
public static void main(String... args) {
Matcher m = p.matcher(s);
if (m.find()) {
String cName = m.group(1);
String[] cVals = m.group(2).split("[\\s,]+");
int n = cVals.length;
try {
Class<?> c = Class.forName(cName);
Object o = Array.newInstance(c, n);
for (int i = 0; i < n; i++) {
String v = cVals[i];
Constructor ctor = c.getConstructor(String.class);
Object val = ctor.newInstance(v);
Array.set(o, i, val);
}
Object[] oo = (Object[])o;
out.format("%s[] = %s%n", cName, Arrays.toString(oo));
// production code should handle these exceptions more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (InstantiationException x) {
x.printStackTrace();
} catch (InvocationTargetException x) {
x.printStackTrace();
}
}
}
}
运行结果:
$ java ArrayCreator
java.math.BigInteger [] = [123, 234, 345]
可以通过java.lang.reflect.Array中的发setXxx(),getXxx()来设置和获取任何原生类型元素,例如,Array.setInt(Object array, int index, int value),Array.getInt(Object object, int index)。而且这些方法支持数据类型的自动扩展,例如可以调用Array.setShort()将short类型的只设置到int的数组中,但是不能调用Array.setLong()将long类型设置到int的数组中,会抛出IllegalArgumentException。 下面的例子是将java.io.BufferedReader的内部char[]替换为一个更大的数组:
import java.io.BufferedReader;
import java.io.CharArrayReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import static java.lang.System.out;
public class GrowBufferedReader {
private static final int srcBufSize = 10 * 1024;
private static char[] src = new char[srcBufSize];
static {
src[srcBufSize - 1] = 'x';
}
private static CharArrayReader car = new CharArrayReader(src);
public static void main(String... args) {
try {
BufferedReader br = new BufferedReader(car);
Class<?> c = br.getClass();
Field f = c.getDeclaredField("cb");
// cb is a private field
f.setAccessible(true);
char[] cbVal = char[].class.cast(f.get(br));
char[] newVal = Arrays.copyOf(cbVal, cbVal.length * 2);
if (args.length > 0 && args[0].equals("grow"))
f.set(br, newVal);
for (int i = 0; i < srcBufSize; i++)
br.read();
// see if the new backing array is being used
if (newVal[srcBufSize - 1] == src[srcBufSize - 1])
out.format("Using new backing array, size=%d%n", newVal.length);
else
out.format("Using original backing array, size=%d%n", cbVal.length);
// production code should handle these exceptions more gracefully
} catch (FileNotFoundException x) {
x.printStackTrace();
} catch (NoSuchFieldException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (IOException x) {
x.printStackTrace();
}
}
}
运行结果:
$ java GrowBufferedReader grow
Using new backing array, size=16384
$ java GrowBufferedReader
Using original backing array, size=8192
示例:
import java.lang.reflect.Array;
import static java.lang.System.out;
public class CreateMatrix {
public static void main(String... args) {
Object matrix = Array.newInstance(int.class, 2, 2);
Object row0 = Array.get(matrix, 0);
Object row1 = Array.get(matrix, 1);
Array.setInt(row0, 0, 1);
Array.setInt(row0, 1, 2);
Array.setInt(row1, 0, 3);
Array.setInt(row1, 1, 4);
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
out.format("matrix[%d][%d] = %d%n", i, j, ((int[][])matrix)[i][j]);
}
}
运行:
$ java CreateMatrix
matrix[0][0] = 1
matrix[0][1] = 2
matrix[1][0] = 3
matrix[1][1] = 4
下面代码实现了相同的功能:
Object matrix = Array.newInstance(int.class, 2);
Object row0 = Array.newInstance(int.class, 2);
Object row1 = Array.newInstance(int.class, 2);
Array.setInt(row0, 0, 1);
Array.setInt(row0, 1, 2);
Array.setInt(row1, 0, 3);
Array.setInt(row1, 1, 4);
Array.set(matrix, 0, row0);
Array.set(matrix, 1, row1);
例如:
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
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)
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)