您的位置:首页 > 编程语言 > Java开发

使用java反射操作类的构造函数,成员变量和成员方法

2008-02-25 11:09 886 查看
在java.lang.reflect包中有三个类Field,Method,Constructor.分别描述域,方法,构造器。参考API,关于这三个类的说明。



在运行时使用反射分析对象,如果访问的是私有域或是私有方法,私有构造函数,会抛出IllegalAccessException.因为反射机制的默认行为受限于java的访问控制,然而,如果一个java程序没有受到安全管理器的控制,就可以覆盖访问控制。为了达到这个目的,需要调用Field,Method,Constructor对象的setAccessible方法,setAccessible方法是AccessibleObject类的一个方法,是Field,Method,Constructor类的公共超类。

setAccessible(true);

不要过多地使用反射:破坏类封装;效率偏低;编译器不容易帮助发现错误,在运行时才会被发现。

我使用反射,是为了写单元测试代码,对运行对象的分析,改变对象的私有域等,达到测试需要的覆盖率。

以下提供代码事例:

测试类:




public class RunBing ...{


private String name;


private int age;


public String sex;






public RunBing() ...{




}






private RunBing(String name) ...{


this.name = name;


}






public void setName(String name) ...{


this.name = name;


}






public void setAge(int age) ...{


this.age = age;


}






public String getName() ...{


return name;


}






public int getAge() ...{


return age;


}






public String run() ...{


return "run method";


}






private String add() ...{


return "add method";


}


}




import java.lang.reflect.Field;


import java.lang.reflect.Method;


import java.lang.reflect.Constructor;








public class ReflectHelp ...{






/** *//**


* 通过构造器取得实例


* @param className 类的全限定名


* @param intArgsClass 构造函数的参数类型


* @param intArgs 构造函数的参数值


*


* @return Object


*/




public static Object getObjectByConstructor(String className,Class[] intArgsClass,Object[] intArgs)...{




Object returnObj= null;




try ...{


Class classType = Class.forName(className);


Constructor constructor = classType.getDeclaredConstructor(intArgsClass); //找到指定的构造方法


constructor.setAccessible(true);//设置安全检查,访问私有构造函数必须


returnObj = constructor.newInstance(intArgs);




} catch (NoSuchMethodException ex) ...{


ex.printStackTrace();




} catch (Exception ex) ...{


ex.printStackTrace();


}


return returnObj;


}




/** *//**


* 修改成员变量的值


* @param Object 修改对象


* @param filedName 指定成员变量名


* @param filedValue 修改的值


*


* @return


*/


public static void modifyFileValue(Object object, String filedName,




String filedValue) ...{


Class classType = object.getClass();


Field fild = null;




try ...{


fild = classType.getDeclaredField(filedName);


fild.setAccessible(true);//设置安全检查,访问私有成员变量必须


fild.set(object, filedValue);




} catch (NoSuchFieldException ex) ...{


ex.printStackTrace();




} catch (Exception ex) ...{


ex.printStackTrace();


}


}






/** *//**


* 访问类成员变量


* @param Object 访问对象


* @param filedName 指定成员变量名


* @return Object 取得的成员变量的值


* */




public static Object getFileValue(Object object, String filedName) ...{


Class classType = object.getClass();


Field fild = null;


Object fildValue = null;




try ...{


fild = classType.getDeclaredField(filedName);


fild.setAccessible(true);//设置安全检查,访问私有成员变量必须


fildValue = fild.get(object);






} catch (NoSuchFieldException ex) ...{


ex.printStackTrace();




} catch (Exception ex) ...{


ex.printStackTrace();


}


return fildValue;


}






/** *//**


* 调用类的方法,包括私有


* @param Object 访问对象


* @param methodName 指定成员变量名


* @param type 方法参数类型


* @param value 方法参数指


* @return Object 方法的返回结果对象


* */


public static Object useMethod(Object object, String methodName,




Class[] type, Class[] value) ...{


Class classType = object.getClass();


Method method = null;


Object fildValue = null;




try ...{


method = classType.getDeclaredMethod(methodName, type);


method.setAccessible(true);//设置安全检查,访问私有成员方法必须


fildValue = method.invoke(object, value);






} catch (NoSuchMethodException ex) ...{


ex.printStackTrace();




} catch (Exception ex) ...{


ex.printStackTrace();


}


return fildValue;


}








public static void main(String[] args) ...{


RunBing runbing = new RunBing();


runbing.setName("aaa");




//访问成员变量


String value = (String) ReflectHelp.getFileValue(runbing, "sex");


System.out.println("value:" + value);


//修改成员变量


ReflectHelp.modifyFileValue(runbing, "sex", "bbb");


System.out.println("value:" + runbing.getName());


//检查修改后的变量值


value = (String) ReflectHelp.getFileValue(runbing, "sex");


System.out.println("value:" + value);




//调用方法




value = (String) ReflectHelp.useMethod(runbing, "add", new Class[] ...{},




new Class[] ...{});


System.out.println("value:" + value);




//使用指定构造函数




Class[] inArgs = new Class[]...{String.class};




Object[] inArgsParms = new Object[]...{"hanj"};


RunBing runBing2 = (RunBing)ReflectHelp.getObjectByConstructor("com.ccit.hj.reflect.RunBing",inArgs,inArgsParms);


value = (String) ReflectHelp.getFileValue(runBing2, "name");


System.out.println("cc -- value:" + value);


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐