Java的反射是很有用的功能,本人从《The Java Developers Almanac 1.4》一书中摘录此部分翻译成了中文,并保留了原文。
错误之处还请原谅,指出则不胜感激。
转载请注明出处。junglesong.yculblog.com
得到成员对象的名称(Getting the Name of a Member Object)
下例显示了如何获取对象的完全名称(包括包路径)和不完全名称。
Class cls = java.lang.String.class;
Method method = cls.getMethods()[0];// 成员方法
Field field = cls.getFields()[0];// 成员变量
Constructor constructor = cls.getConstructors()[0];// 构造函数
String name;
// 获取对象的完全名称
name = cls.getName(); // java.lang.String
name = cls.getName()+"."+field.getName(); // java.lang.String.CASE_INSENSITIVE_ORDER
name = constructor.getName(); // java.lang.String
name = cls.getName()+"."+method.getName(); // java.lang.String.hashCode
// 获取对象的不完全名称
name = cls.getName().substring(cls.getPackage().getName().length()+1); // String
name = field.getName(); // CASE_INSENSITIVE_ORDER
name = constructor.getName().substring(cls.getPackage().getName().length()+1); // String
name = method.getName(); // hashCode
重载缺省访问权限(Overriding Default Access)
By default, a reflected object enforces the access as defined by the Java language. For example, by default you cannot retrieve the value from a Field object if the Field object represents a private field. To bypass these access checks, you call setAccessible() on the reflected object. However, the program may not have permission to call setAccessible(), in which case SecurityException is thrown.
一般来说,反射对象的访问权限由Java语言定义好了。比如说,你不能从一个私有方法中取出值。为了突破这一限制,你可以使用setAccessible()这个方法。但有时程序没有调用setAccessible的权限,此时会抛出安全性异常。
field.setAccessible(true);
constructor.setAccessible(true);
method.setAccessible(true);
创建一个代理对象(Creating a Proxy Object)
public interface MyInterface {
void method();
}
public class MyInterfaceImpl implements MyInterface {
public void method() {
}
}
public class ProxyClass implements InvocationHandler {
Object obj;
public ProxyClass(Object o) {
obj = o;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result = null;
try {
// Do something before the method is called ...
result = m.invoke(obj, args);
} catch (InvocationTargetException e) {
} catch (Exception eBj) {
} finally {
// Do something after the method is called ...
}
return result;
}
}
// 此片断创建了一个MyInterface对象的代理(This fragment creates a proxy for a MyInterface object.)
MyInterface myintf = (MyInterface)Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
new Class[]{MyInterface.class},
new ProxyClass(new MyInterfaceImpl()));
// 调用方法(Invoke the method)
myintf.method();
列举一个对象的公有方法(Listing the Modifiers of a Class Object)
int mods = cls.getModifiers();
if (Modifier.isPublic(mods)) {
// class is public
}
列举一个成员变量的公有方法(Listing the Modifiers of a Member Object)
Field, Constructor, and Method are all subclasses of Member.
成员,构造函数和方法都是成员的子集。
// Modifiers from a field.
int mods = member.getModifiers();
if (Modifier.isPublic(mods)) {
// member is public
}
得到一个类对象的所有成员对象(Getting the Field Objects of a Class Object)
There are three ways of obtaining a Field object from a Class object.
有三种方法一个类对象的所有成员对象。
Class cls = java.awt.Point.class;
// 1.通过定义成员列表(By obtaining a list of all declared fields.)
Field[] fields = cls.getDeclaredFields();
// 2.通过定义和继承的成员列表(By obtaining a list of all public fields, both declared and inherited.)
fields = cls.getFields();
for (int i=0; i<fields.length; i++) {
Class type = fields[i].getType();
process(fields[i]);
}
// 3.通过指定的成员(By obtaining a particular Field object.)
// This example retrieves java.awt.Point.x.
try {
Field field = cls.getField("x");
process(field);
} catch (NoSuchFieldException e) {
}
对一个成员进行设值取值操作(Getting and Setting the Value of a Field)
下例必须保证成员是整形的(This example assumes that the field has the type int. )
try {
// 取值Get value
field.getInt(object);
// 设值Set value
field.setInt(object, 123);
// 对静态成员取值Get value of a static field
field.getInt(null);
// 对静态成员设值Set value of a static field
field.setInt(null, 123);
} catch (IllegalAccessException e) {
}
得到类对象的构造函数(Getting a Constructor of a Class Object)
有两种途径得到类对象的构造函数There are two ways of obtaining a Constructor object from a Class object.
// 1.通过构造函数列表(By obtaining a list of all Constructors object.)
Constructor[] cons = cls.getDeclaredConstructors();
for (int i=0; i<cons.length; i++) {
Class[] paramTypes = cons[i].getParameterTypes();
process(cons[i]);
}
// 2.通过指定的处理(By obtaining a particular Constructor object.)
// This example retrieves java.awt.Point(int, int).
try {
Constructor con = java.awt.Point.class.getConstructor(new Class[]{int.class, int.class});
process(con);
} catch (NoSuchMethodException e) {
}
通过构造函数创建对象(Creating an Object Using a Constructor Object)
下例通过构造函数 Point(int,int)创建了一个Point对象(This example creates a new Point object from the constructor Point(int,int). )
try {
java.awt.Point obj = (java.awt.Point)con.newInstance(
new Object[]{new Integer(123), new Integer(123)});
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
得到类对象的成员函数(Getting the Methods of a Class Object)
有三种不同途径得到类对象的成员函数(There are three ways of obtaining a Method object from a Class object. )
Class cls = java.lang.String.class;
// 1.通过定义成员函数列表(By obtaining a list of all declared methods.)
Method[] methods = cls.getDeclaredMethods();
// 2.通过定义和继承的成员函数列表(By obtaining a list of all public methods, both declared and inherited.)
methods = cls.getMethods();
for (int i=0; i<methods.length; i++) {
Class returnType = methods[i].getReturnType();
Class[] paramTypes = methods[i].getParameterTypes();
process(methods[i]);
}
// 3.通过指定的成员函数(By obtaining a particular Method object.)
// This example retrieves String.substring(int).
try {
Method method = cls.getMethod("substring", new Class[] {int.class});
process(method);
} catch (NoSuchMethodException e) {
}
通过方法调用成员函数对象(Invoking a Method Using a Method Object)
try {
Object result = method.invoke(object, new Object[] {param1, param2, ..., paramN});
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
判断一个对象是否数组(Determining If an Object Is an Array)
boolean b = object.getClass().isArray();
if (b) {
// object is an array
}
得到一个数组对象的长度与维度(Getting the Length and Dimensions of an Array Object)
The length of an array is the number of elements of the array. The dimensions of an array type of int[][][] is three.
Object o = new int[1][2][3];
// 得到数组长度(Get length)
int len = Array.getLength(o); // 1
// 得到数组维度(Get dimension)
int dim = getDim(o); // 3
// If `array' is an array object returns its dimensions; otherwise returns 0
// 以下函数当对象array是数组时返回其维度,否则返回0.
public static int getDim(Object array) {
int dim = 0;
Class cls = array.getClass();
while (cls.isArray()) {
dim++;
cls = cls.getComponentType();
}
return dim;
}
得到数组元素的类型(Getting the Component Type of an Array Object)
The component type of an array is the type of an array's elements. For example, the component type of int[] is int. The component type of int[][] is int[].
object.getClass().getComponentType();
创建数组(Creating an Array)
// An array of 10 ints.
int[] ints = (int[])Array.newInstance(int.class, 10);
// An array of 10 int-arrays.
int[][] ints2 = (int[][])Array.newInstance(int[].class, 10);
// A 10x20 2-dimenional int array.
ints2 = (int[][])Array.newInstance(int.class, new int[]{10, 20});
扩充数组(Expanding an Array)
The length of an array cannot be changed. The closest thing to expanding an array is to create a larger one of the same type and copy the contents from the old array.
数组的长度不能更改.要更改的话最简单的方法就是创建一个更长的数组并把原数组的值拷贝进去.
Object newArray = Array.newInstance(array.getClass().getComponentType(), Array.getLength(array)*2);
System.arraycopy(array, 0, newArray, 0, Array.getLength(array));
存取数组中的元素的值(Getting and Setting the Value of an Element in an Array Object)
// 取得第三个元素的值(Get the value of the third element.)
Object o = Array.get(array, 2);
// 设定第三个元素的值(Set the value of the third element.)
Array.set(array, 2, newValue);
