前言:本文主要介绍反射的经常使用的构造函数,成员变量,成员方法的使用,从网络上搜索了一些资料,自己写了列子,主要为阅读者初级使用反射做指导。
一、Class类的对象
获得Class对象的方法
下表列出了几种得到Class类的方法,以供大家参考。
Class object 诞生管道 |
示例 |
运用getClass() 注:每个class 都有此函数 |
String str = "abc"; Class c1 = str.getClass(); |
运用 Class.getSuperclass() |
Button b = new Button(); Class c1 = b.getClass(); Class c2 = c1.getSuperclass(); |
运用static method Class.forName() (最常被使用) |
Class c1 = Class.forName ("java.lang.String"); Class c2 = Class.forName ("java.awt.Button"); Class c3 = Class.forName ("java.util.LinkedList$Entry"); Class c4 = Class.forName ("I"); Class c5 = Class.forName ("[I"); |
运用 .class 语法 |
Class c1 = String.class; Class c2 = java.awt.Button.class; Class c3 = Main.InnerClass.class; Class c4 = int.class; Class c5 = int[].class; |
运用 primitive wrapper classes 的TYPE 语法 |
Class c1 = Boolean.TYPE; Class c2 = Byte.TYPE; Class c3 = Character.TYPE; Class c4 = Short.TYPE; Class c5 = Integer.TYPE; Class c6 = Long.TYPE; Class c7 = Float.TYPE; Class c8 = Double.TYPE; Class c9 = Void.TYPE; |
获取Class对象的一些基本信息
如下表。
Java class 内部模块 |
Java class 内部模块说明 |
相应之Reflection API,多半为Class methods。 |
返回值类型(return type) |
package |
class隶属哪个package |
getPackage() |
Package |
import |
class导入哪些classes |
无直接对应之API。可间接获取。 |
|
modifier |
class(或methods, fields)的属性 |
int getModifiers() Modifier.toString(int) Modifier.isInterface(int) |
int String bool |
class name or interface name |
class/interface |
名称getName() |
String |
type parameters |
参数化类型的名称 |
getTypeParameters() |
TypeVariable <Class>[] |
base class |
base class(只可能一个) |
getSuperClass() |
Class |
implemented interfaces |
实现有哪些interfaces |
getInterfaces() |
Class[] |
inner classes |
内部classes |
getDeclaredClasses() |
Class[] |
outer class |
如果我们观察的class 本身是inner classes,那么相对它就会有个outer class。 |
getDeclaringClass() |
Class |
上表中,列出了一些Java class内部信息的获取方式。所采用的方法几乎都是调用Class对象的成员方法(由此你就可以了解到Class类的用处了吧)。
二、类中最重要的三个信息
构造函数
获取构造函数的方法有以下几个:
ConstructorgetConstructor(Class[] params)
Constructor[]getConstructors()
ConstructorgetDeclaredConstructor(Class[] params)
Constructor[]getDeclaredConstructors()
Class[] params为目标类的构造函数参数类型数组,具体见以下的举例
不带Declared关键字的函数(如:getConstructor)只能获取到公有的构造函数,
带Declared关键字的函数(如:getDeclaredConstructor)能获取到飞共有的构造函数,即所有访问保护机制的构造函数。
成员函数
和获取构造函数的方法类似,获取成员函数的方法有以下一些:
MethodgetMethod(String name, Class[] params)
Method[]getMethods()
MethodgetDeclaredMethod(String name, Class[] params)
Method[]getDeclaredMethods()
其中需要注意,String name参数,需要写入方法名。关于访问权限和确定性的问题,和构造函数基本一致。
成员变量
获取成员变量的方法与上面两种方法类似,具体如下:
FieldgetField(String name)
Field[]getFields()
FieldgetDeclaredField(String name)
Field[]getDeclaredFields()
其中,String name参数,需要写入变量名。关于访问权限和确定性的问题,与前面两例基本一致。
三、使用举例
我们举一个两个数相加的列子
MathPlus类代码:
package cn.cq.shenyun; public class MathPlus { public int num1=0; public int num2=0; //默认构造函数 public MathPlus(){ } //带两个整形参数的构造函数 public MathPlus(int nummber1,int nummber2){ num1=nummber1; num2=nummber2; } //将对象内的两个成员相继返回 public int add1(){ return num1+num2; } //将传入的两整形参数相加返回 public int add2(int nummber1,int nummber2){ return nummber1+nummber2; } }
MathMain类:该类是主函数所在类,利用反射操作MathPlus类
package cn.cq.shenyun; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class MathMain { public static void main(String[] args) { test1(); test2(); test3(); test4(); } //用无参构造函数构造对象,再调用无参方法add1 public static void test1(){ try { //获取Class Class<?> cls = Class.forName("cn.cq.shenyun.MathPlus"); //用默认构造函数构造对象 Constructor<?> con=cls.getConstructor(); Object mathobj=con.newInstance(); //如果是用无参构造,可直接用Class的newInstance方法,都够构造对象 //Object mathobj=cls.newInstance(); //调用无参数对象方法add1 Method method=cls.getMethod("add1");//指定调用的方法 add1 int result=(Integer)method.invoke(mathobj);//调用mathobj1 的add1方法 System.out.println("----test1 用无参构造函数构造对象,再调用无参方法add1----"); System.out.println(" test1 result="+result); }catch (Exception e) { } } //利用反射改变对象的成员变量 public static void test2(){ try{ //获取Class Class<?> cls = Class.forName("cn.cq.shenyun.MathPlus"); //用默认构造函数构造对象 Constructor<?> con=cls.getConstructor(); Object mathobj=con.newInstance(); //修改mathobj对象中num1的值 Field field1=cls.getDeclaredField("num1"); field1.setInt(mathobj, 2); //修改mathobj对象中num2的值 Field field2=cls.getDeclaredField("num2"); field2.setInt(mathobj, 3); //调用无参数对象方法add1 Method method=cls.getMethod("add1");//指定调用的方法 add1 int result=(Integer)method.invoke(mathobj);//调用mathobj1 的add1方法 //System.out.println("test2 number1="+field1.getInt(mathobj)); //System.out.println("test2 number2="+field2.getInt(mathobj)); System.out.println("----test2 利用反射改变对象的成员变量----"); System.out.println(" test2 result="+result+",number1="+field1.getInt(mathobj)+",number2="+field2.getInt(mathobj)); }catch (Exception e) { e.printStackTrace(); } } //调用有参构造函数 public static void test3(){ try{ //获取Class Class<?> cls = Class.forName("cn.cq.shenyun.MathPlus"); //设定构造函数的参数类型 Class<?>[] parTypes=new Class<?>[2]; parTypes[0]=int.class; parTypes[1]=int.class; //获取构造器 Constructor<?> con=cls.getConstructor(parTypes);//----------------重点注意,参数变化了 //初始化构造参数 Object[] pars=new Object[2]; pars[0]=4; pars[1]=5; //构造对象 Object mathobj=con.newInstance(pars); //----------------重点注意,参数变化了 //调用add1 Method method=cls.getMethod("add1");//指定调用的方法 add1 int result=(Integer)method.invoke(mathobj);//调用mathobj 的add1方法 System.out.println("----test3 调用有参构造函数----"); System.out.println(" test3 result="+result); }catch (Exception e) { } } //调用有参数的函数 add2 public static void test4(){ try{ //获取Class Class<?> cls = Class.forName("cn.cq.shenyun.MathPlus"); //用默认构造函数构造对象 Constructor<?> con=cls.getConstructor(); Object mathobj=con.newInstance(); //调用add2 Class<?>[] parTypes=new Class<?>[2]; parTypes[0]=int.class; parTypes[1]=int.class; Method method=cls.getMethod("add2",parTypes);//指定调用的方法 add2 Object[] pars=new Object[2]; pars[0]=6; pars[1]=7; int result=(Integer)method.invoke(mathobj,pars);//调用mathobj 的add2方法 System.out.println("----test4 调用有参数的函数 add2----"); System.out.println(" test4 result="+result); }catch (Exception e) { } } }
代码下载地址
百度网盘分享地址:http://pan.baidu.com/share/link?shareid=3185562225&uk=4093749335