前言:本文主要介绍反射的经常使用的构造函数,成员变量,成员方法的使用,从网络上搜索了一些资料,自己写了列子,主要为阅读者初级使用反射做指导。
一、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