JAVA反射机制是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程式在运行时通过Reflection APIs取得任何一个已知名称的class的内部资讯,包括其modifiers(诸如public, private,static等等)、superclass(例如Object)、interfaces(例如Cloneable),也包括fields和methods的所有资讯,并在运行时调用任意一个对象的方法;生成动态代理。下面以一段代码来看一下主要的Reflection APIs,代码中有相应的注释。
- importjava.lang.reflect.Array;
- importjava.lang.reflect.Constructor;
- importjava.lang.reflect.Field;
- importjava.lang.reflect.InvocationTargetException;
- importjava.lang.reflect.Method;
- importjava.lang.reflect.Modifier;
- publicclassGoods
- {
- privateStringid;
- privatedoubleprice;
- publicGoods(){
- System.out.println("itisapen");
- }
- publicGoods(Strings1,Strings2){
- System.out.println(s1+"*"+s2);
- }
- publicStringgetId()
- {
- System.out.println(id);
- returnid;
- }
- publicvoidsetId(Stringid)
- {
- this.id=id;
- }
- publicStringaddName(Stringstr1,Stringstr2){
- returnstr1+str2;
- }
- /**
- *@throwsClassNotFoundException
- *@throwsIllegalAccessException
- *@throwsInstantiationException
- *@throwsNoSuchMethodException
- *@throwsSecurityException
- *@throwsInvocationTargetException
- *@throwsIllegalArgumentException
- *@throwsNoSuchFieldException
- *@功能描述
- *@输入参数
- *@反馈值
- */
- publicstaticvoidmain(String[]args)throwsClassNotFoundException,InstantiationException,IllegalAccessException,SecurityException,NoSuchMethodException,IllegalArgumentException,InvocationTargetException,NoSuchFieldException
- {
- //TODOAuto-generatedmethodstub
- Stringstr="com.xtlh.sinye.Goods";
- Classc=Class.forName(str);
- Objectobj=c.newInstance();//初始化一个Goods的对象
- /**
- *//这里设置属性的值调用setId()方法,类型用Class[],参数用Object[]
- */
- Methodm=c.getMethod("setId",newClass[]{Class.forName("java.lang.String")});
- m.invoke(obj,newObject[]{"it'sapple"});
- System.out.println("---------------------------------------------------------------------");
- /**
- *//这里是里获取属性的值调用getId()方法
- */
- m=c.getMethod("getId",newClass[]{});
- m.invoke(obj,newObject[]{});
- System.out.println("---------------------------------------------------------------------");
- /**
- *//获得类中声明的方法
- */
- Methodme[]=c.getDeclaredMethods();
- for(inti=0;i<me.length;i++){
- System.out.println("method["+i+"]="+me[i].toString());
- }
- System.out.println("---------------------------------------------------------------------");
- /**
- *//模拟instanceof操作符
- */
- booleanb1=c.isInstance(newInteger(34));
- System.out.println("GoodsisainstanceofInteger?"+b1);
- booleanb2=c.isInstance(newGoods());//这里调用了无参的构造方法
- System.out.println("GoodsisainstanceofGoods?"+b2);
- System.out.println("---------------------------------------------------------------------");
- /**
- *//找出类的方法,类的名称,类的方法的参数,类的方法的返回类型
- */
- Methodmed[]=c.getDeclaredMethods();
- Methodmed1[]=c.getMethods();//从字面意思可以看出来,这里找到所有的方法,即可以找到继承来的方法等
- for(inti=0;i<med.length;i++){
- Methodmee=med[i];
- System.out.println("method#"+i+"name="+mee.getName());
- System.out.println("declaringclass="+mee.getDeclaringClass());
- //方法的参数类型
- Classpvec[]=m.getParameterTypes();
- for(intj=0;j<pvec.length;j++){
- System.out.println("parameter#"+j+"="+pvec[j]);
- }
- //方法的异常
- Classevec[]=m.getExceptionTypes();
- for(intj=0;j<evec.length;j++){
- System.out.println("exception#"+j+""+evec[j]);
- }
- //方法的返回类型
- System.out.println("returntype="+mee.getReturnType());
- }
- System.out.println("---------------------------------------------------------------------");
- /**
- *//获取类的构造函数
- */
- Constructorctorlist[]=c.getDeclaredConstructors();
- for(inti=0;i<ctorlist.length;i++){
- Constructorcons=ctorlist[i];
- System.out.println("Constructor#"+i+"name="+cons.getName());
- Class[]consParaType=cons.getParameterTypes();//获得构造函数的参数类型
- if(consParaType.length==0){
- System.out.println("Constructorhavenoparameters");
- }else{
- for(intj=0;j<consParaType.length;j++){
- System.out.println("ConstructorParametertype#"+j+"name="+consParaType[j]);
- }
- }
- }
- System.out.println("---------------------------------------------------------------------");
- /**
- *//获取类的属性
- */
- Fieldfieldlist[]=c.getDeclaredFields();
- for(inti=0;i<fieldlist.length;i++){
- Fieldfield=fieldlist[i];
- System.out.println("Filed#"+i+"name="+field.getName());//属性名称
- System.out.println("Filed#"+i+"type="+field.getType());//属性类型
- intmod=field.getModifiers();
- System.out.println("modifiers="+Modifier.toString(mod));//属性的修饰符private/public/protected
- }
- System.out.println("---------------------------------------------------------------------");
- /**
- *//根据方法的名称来执行方法
- */
- Classcls=Class.forName("com.xtlh.sinye.Goods");
- Classpartypes[]=newClass[2];
- partypes[0]=String.class;//更多类型Long.TYPEInteger.TYPE,或者使用Long.class、Integer.class
- partypes[1]=Class.forName("java.lang.String");
- Methodmeth=cls.getMethod("addName",partypes);
- Goodsgoods=newGoods();
- Objectarglist[]=newObject[2];
- arglist[0]=newString("love");
- arglist[1]=newString("grape");
- Objectretobj=meth.invoke(goods,arglist);
- Stringretval=(String)retobj;
- System.out.println(retval);
- System.out.println("---------------------------------------------------------------------");
- /**
- *创建对象,根据指定的参数类型找到相应的构造函数并执行它,以创建一个新的对象实例。使用这种方法可以在程序运行时动态地创建对象,而不是在编译的时候创建对象,这一点非常有价值
- */
- Classclss=Class.forName("com.xtlh.sinye.Goods");
- Classpartypess[]=newClass[2];
- partypess[0]=String.class;
- partypess[1]=String.class;
- Constructorct=clss.getConstructor(partypess);
- Objectarglists[]=newObject[2];
- arglists[0]=newString("hello");
- arglists[1]=newString("orange");
- Objectretobjs=ct.newInstance(arglists);
- System.out.println("---------------------------------------------------------------------");
- /**
- *//改变属性的值
- */
- Classccc=Class.forName("com.xtlh.sinye.Goods");
- Fieldfld=ccc.getDeclaredField("price");
- Goodsgoods1=newGoods();
- System.out.println("price="+goods1.price);
- fld.setDouble(goods1,25.0);
- System.out.println("price="+goods1.price);
- System.out.println("---------------------------------------------------------------------");
- /**
- *//简单使用数组,创建了10个单位长度的String数组,为第5个位置的字符串赋了值,最后将这个字符串从数组中取得并打印了出来
- */
- Classcla=Class.forName("java.lang.String");
- Objectarr=Array.newInstance(cla,10);
- Array.set(arr,5,"helloWatermelon");
- Strings=(String)Array.get(arr,5);
- System.out.println(s);
- System.out.println("---------------------------------------------------------------------");
- /**
- *//复杂数组使用,例中创建了一个5x10x15的整型数组,并为处于[3][5][10]的元素赋了值为37。注意,多维数组实际上就是数组的数组,例如,第一个Array.get之后,arrobj是一个10x15的数组。进而取得其中的一个元素,即长度为15的数组,并使用Array.setInt为它的第10个元素赋值。
- 注意创建数组时的类型是动态的,在编译时并不知道其类型。
- */
- intdims[]=newint[]{5,10,15};
- Objectarray=Array.newInstance(Integer.TYPE,dims);
- Objectarrobj=Array.get(array,3);
- Classcl=arrobj.getClass().getComponentType();
- System.out.println(cl);
- arrobj=Array.get(arrobj,5);
- Array.setInt(arrobj,10,37);
- intarrcast[][][]=(int[][][])array;
- System.out.println(arrcast[3][5][10]);
- }
- }