总结自《Java核心技术卷Ⅰ》
一.使用反射编写泛型数组代码
java.lang.reflect包中的Array类允许动态地创建数组。
我们要学习的是如何让一个特殊类型的数组转换成一个Object类型的数组.
实现这一目的我们需要用到的方法有:
学习例子:
package day01;
import java.lang.reflect.*;
import java.util.*;
/**
* This program demonstrates the use of reflection for manipulating arrays.
* @version 1.2 2012-05-04
* @author Cay Horstmann
*/
public class CopyOfTest
{
public static void main(String[] args)
{
int[] a = { 1, 2, 3 };
a = (int[]) goodCopyOf(a, 10);
System.out.println(Arrays.toString(a));
String[] b = { "Tom", "Dick", "Harry" };
b = (String[]) goodCopyOf(b, 10);
System.out.println(Arrays.toString(b));
System.out.println("The following call will generate an exception.");
b = (String[]) badCopyOf(b, 10);
}
/**
* This method attempts to grow an array by allocating a new array and copying all elements.
* @param a the array to grow
* @param newLength the new length
* @return a larger array that contains all elements of a. However, the returned array has
* type Object[], not the same type as a
*/
public static Object[] badCopyOf(Object[] a, int newLength) // not useful
{
Object[] newArray = new Object[newLength];
System.arraycopy(a, 0, newArray, 0, Math.min(a.length, newLength));
return newArray;
}
/**
* This method grows an array by allocating a new array of the same type and
* copying all elements.
* @param a the array to grow. This can be an object array or a primitive
* type array
* @return a larger array that contains all elements of a.
*/
public static Object goodCopyOf(Object a, int newLength)
{
Class cl = a.getClass();
if (!cl.isArray()) return null;
Class componentType = cl.getComponentType();//获得数组元素类型
int length = Array.getLength(a);//获得数组长度
Object newArray = Array.newInstance(componentType, newLength);
System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength));
return newArray;
}
}
二.调用任意方法
反射机制允许我们调用任何的方法。
在Method中有一个invoke的方法,它允许调用包装在当前Method对象中的方法。
例子:
package methods;
import java.lang.reflect.*;
/**
* This program shows how to invoke methods through reflection.
* @version 1.2 2012-05-04
* @author Cay Horstmann
*/
public class MethodTableTest
{
public static void main(String[] args) throws Exception
{
// get method pointers to the square and sqrt methods
Method square = MethodTableTest.class.getMethod("square", double.class);
Method sqrt = Math.class.getMethod("sqrt", double.class);
// print tables of x- and y-values
printTable(1, 10, 10, square);
printTable(1, 10, 10, sqrt);
}
/**
* Returns the square of a number
* @param x a number
* @return x squared
*/
public static double square(double x)
{
return x * x;
}
/**
* Prints a table with x- and y-values for a method
* @param from the lower bound for the x-values
* @param to the upper bound for the x-values
* @param n the number of rows in the table
* @param f a method with a double parameter and double return value
*/
public static void printTable(double from, double to, int n, Method f)
{
// print out the method as table header
System.out.println(f);
double dx = (to - from) / (n - 1);
for (double x = from; x <= to; x += dx)
{
try
{
double y = (Double) f.invoke(null, x);
System.out.printf("%10.4f | %10.4f%n", x, y);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}