怎么利用java放射机制进行对象的实例化等操作

来源:互联网 发布:python strip 多个 编辑:程序博客网 时间:2024/06/05 09:29

大家看demo就明白了:

User.java:

package test;/** * @编写人: yh.zeng * @编写时间:2017-7-10 下午9:26:18 * @文件描述: todo */public class User {private String userName; // 用户名public Integer age; // 年龄private String getUserName() {return userName;}private void setUserName(String userName) {this.userName = userName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}

Test.java:

package test;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;/** * @编写人: yh.zeng * @编写时间:2017-7-11 下午1:08:05 * @文件描述: todo */public class Test {/** * 获取类定义的非public字段(如private、protected等)     * @param targetClass 目标类 * @param fieldName   字段名 * @return * @throws Exception */public static Field getPrivateField(Class targetClass, String fieldName) throws Exception{Field field = targetClass.getDeclaredField(fieldName);field.setAccessible(true); //不检查该字段的访问权限,否则使用Field.get()(即获取不到该字段数据的时候),可能会报错return field;}/*** * 获取类定义的pulic字段 * @param targetClass  目标类 * @param fieldName    字段名 * @return * @throws Exception */public static Field getPublicField(Class targetClass, String fieldName) throws Exception{return targetClass.getField(fieldName);}/** * 获取类定义的非public方法(如private、protected等) * @param targetClass     目标类 * @param methodName      方法名 * @param parameterTypes  方法参数类型 * @return * @throws Exception */public static Method getPrivateMethod(Class targetClass, String methodName, Class<?>... parameterTypes) throws Exception{Method method = targetClass.getDeclaredMethod(methodName, parameterTypes);method.setAccessible(true); //不检查该方法的访问权限,否则使用Method.invoke()(即调用实例对象的该方法的时候),可能会报错return method;}/** * 获取类定义的public方法 * @param targetClass     目标类 * @param methodName      方法名 * @param parameterTypes  方法参数类型 * @return * @throws Exception */public static Method getPublicMethod(Class targetClass, String methodName, Class<?>... parameterTypes) throws Exception{return targetClass.getMethod(methodName, parameterTypes);}/** * 获取类定义个非public构造方法,如(如private、protected等) * @param targetClass     目标类 * @param parameterTypes  构造方法参数类型 * @return * @throws Exception */public static Constructor getPrivateConstructor(Class targetClass, Class<?>... parameterTypes) throws Exception{Constructor constructor = targetClass.getDeclaredConstructor(parameterTypes);constructor.setAccessible(true); //不检查该构造方法的访问权限,否则使用Constructor.newInstance()(即实例化对象的时候),可能会报错    return constructor;}/** * 获取类定义个public构造方法 * @param targetClass     目标类 * @param parameterTypes  构造方法参数类型 * @return * @throws Exception */public static Constructor getPublicConstructor(Class targetClass, Class<?>... parameterTypes) throws Exception{return targetClass.getConstructor(parameterTypes);}public static void main(String args[]) throws Exception{Class clazz = Class.forName("test.User");Object instance = getPublicConstructor(clazz).newInstance();//获取字段值Field userNameField = getPrivateField(clazz, "userName");System.out.println("userName = " + userNameField.get(instance) );Field ageField = getPrivateField(clazz, "age");System.out.println("age = " + ageField.get(instance) );//调用相应方法设值Method setUserNameMehod = getPrivateMethod(clazz, "setUserName", String.class);setUserNameMehod.invoke(instance, "aa");Method setAge = getPrivateMethod(clazz, "setAge", Integer.class);setAge.invoke(instance, 18);//再次获取字段值System.out.println("userName = " + userNameField.get(instance) );System.out.println("age = " + ageField.get(instance) );}}

Test.java程序运行结果如下:

userName = nullage = nulluserName = aaage = 18

备注:

  • 获取非public字段,就一定要使用Class.getDeclaredField来获取
  • 获取public字段,即可以使用Class.getField,也可以使用Class.getDeclaredField,所以推荐字段的获取一律使用Class.getDeclaredField
  • 获取非public方法,就一定要使用Class.getDeclaredMethod来获取
  • 获取public方法,即可以使用Class.getMethod,也可以使用Class.getDeclaredMethod,所以推荐方法的获取一律使用Class.getDeclaredMethod
  • 获取非public构造方法,就一定要使用Class.getDeclaredConstructor来获取
  • 获取public构造方法,即可以使用Class.getConstructor,也可以使用Class.getDeclaredConstructor,所以推荐方法的获取一律使用Class.getDeclaredConstructor
  • 字段、方法以及构造方法,一定要设置setAccessible(true),否则可能会报无权限访问的错误


阅读全文
0 0
原创粉丝点击