正文
public Field getDeclaredField(String name)
Field也有很多方法,可以获取字段的信息,也可以通过Field访问和操作指定对象中该字段的值,基本方法有:
//获取字段的名称
public String getName()
//判断当前程序是否有该字段的访问权限
public boolean isAccessible()
//flag设为true表示忽略Java的访问检查机制,以允许读写非public的字段
public void setAccessible(boolean flag)
//获取指定对象obj中该字段的值
public Object get(Object obj)
//将指定对象obj中该字段的值设为value
public void set(Object obj, Object value)
在get/set方法中,对于静态变量,obj被忽略,可以为null,如果字段值为基本类型,get/set会自动在基本类型与对应的包装类型间进行转换,对于private字段,直接调用get/set会抛出非法访问异常IllegalAccessException,应该先调用setAccessible(true)以关闭Java的检查机制。
看段简单的示例代码:
List
obj = Arrays.asList(new String[]{"老马","编程"});
Class> cls = obj.getClass();
for(Field f : cls.getDeclaredFields()){
f.setAccessible(true);
System.out.println(f.getName()+" - "+f.get(obj));
}
代码比较简单,就不赘述了。我们在
ThreadLocal一节
介绍过利用反射来清空ThreadLocal,这里重复下其代码,含义就比较清楚了:
protected void beforeExecute(Thread t, Runnable r) {
try {
//使用反射清空所有ThreadLocal
Field f = t.getClass().getDeclaredField("threadLocals");
f.setAccessible(true);
f.set(t, null);
} catch (Exception e) {
e.printStackTrace();
}
super.beforeExecute(t, r);
}
除了以上方法,Field还有很多别的方法,比如:
//返回字段的修饰符
public int getModifiers()
//返回字段的类型
public Class> getType()
//以基本类型操作字段
public void setBoolean(Object obj, boolean z)
public boolean getBoolean(Object obj)
public void setDouble(Object obj, double d)
public double getDouble(Object obj)
//查询字段的注解信息
public
T getAnnotation(Class
annotationClass)
public Annotation[] getDeclaredAnnotations()
getModifiers返回的是一个int,可以通过Modifier类的静态方法进行解读,比如,假定Student类有如下字段:
public static final int MAX_NAME_LEN = 255;
可以这样查看该字段的修饰符:
Field f = Student.class.getField("MAX_NAME_LEN");
int mod = f.getModifiers();
System.out.println(Modifier.toString(mod));
System.out.println("isPublic: " + Modifier.isPublic(mod));
System.out.println("isStatic: " + Modifier.isStatic(mod));
System.out.println("isFinal: " + Modifier.isFinal(mod));
System.out.println("isVolatile: " + Modifier.isVolatile(mod));
输出为:
public static final
isPublic: true
isStatic: true
isFinal: true
isVolatile: false
关于注解,我们下节再详细介绍。
方法信息
类中定义的静态和实例方法都被称为方法,用类Method表示,Class有四个获取方法信息的方法:
//返回所有的public方法,包括其父类的,如果没有方法,返回空数组
public Method[] getMethods()
//返回本类声明的所有方法,包括非public的,但不包括父类的
public Method[] getDeclaredMethods()
//返回本类或父类中指定名称和参数类型的public方法,找不到抛出异常NoSuchMethodException
public Method getMethod(String name, Class>... parameterTypes)
//返回本类中声明的指定名称和参数类型的方法,找不到抛出异常NoSuchMethodException
public Method getDeclaredMethod(String name, Class>... parameterTypes)
Method也有很多方法,可以获取方法的信息,也可以通过Method调用对象的方法,基本方法有:
//获取方法的名称
public String getName()
//flag设为true表示忽略Java的访问检查机制,以允许调用非public的方法
public void setAccessible(boolean flag)
//在指定对象obj上调用Method代表的方法,传递的参数列表为args
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
对invoke方法,如果Method为静态方法,obj被忽略,可以为null,args可以为null,也可以为一个空的数组,方法调用的返回值被包装为Object返回,如果实际方法调用抛出异常,异常被包装为InvocationTargetException重新抛出,可以通过getCause方法得到原异常。
看段简单的示例代码:
Class> cls = Integer.class;
try {
Method method = cls.getMethod("parseInt", new Class[]{String.class});
System.out.println(method.invoke(null, "123"));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Method还有很多方法,可以获取方法的修饰符、参数、返回值、注解等信息,比如:
//获取方法的修饰符,返回值可通过Modifier类进行解读
public int getModifiers()
//获取方法的参数类型
public Class>[] getParameterTypes()
//获取方法的返回值类型
public Class> getReturnType()
//获取方法声明抛出的异常类型
public Class>[] getExceptionTypes()
//获取注解信息
public Annotation[] getDeclaredAnnotations()
public
T getAnnotation(Class
annotationClass)
//获取方法参数的注解信息
public Annotation[][] getParameterAnnotations()
创建对象和构造方法
Class有一个方法,可以用它来创建对象:
public T newInstance() throws InstantiationException, IllegalAccessException