Fieldfield=fields[i];
StringfieldName=field.getName();
StringfirstLetter=fieldName.substring(0,1).toUpperCase();
//获得和属性对应的getXXX()方法的名字
StringgetMethodName="get"+firstLetter+fieldName.substring
(1);
//获得和属性对应的setXXX()方法的名字
StringsetMethodName="set"+firstLetter+fieldName.substring
(1);
//获得和属性对应的getXXX()方法
MethodgetMethod=classType.getMethod(getMethodName,newClass[]{});
//获得和属性对应的setXXX()方法
MethodsetMethod=classType.getMethod(setMethodName,newClass[]{field.getType()});
//调用原对象的getXXX()方法
Objectvalue=getMethod.invoke(object,newObject[]{});
System.out.println(fieldName+":
"+value);
//调用拷贝对象的setXXX()方法
setMethod.invoke(objectCopy,newObject[]{value});
}
returnobjectCopy;
}
publicstaticvoidmain(String[]args)throwsException{
Customercustomer=newCustomer("Tom",21);
customer.setId(newLong
(1));
CustomercustomerCopy=(Customer)newReflectTester().copy(customer);
System.out.println("Copyinformation:
"+customerCopy.getId()+""
+customerCopy.getName()+""+customerCopy.getAge());
}
}
classCustomer{
privateLongid;
privateStringname;
privateintage;
publicCustomer(){
}
publicCustomer(Stringname,intage){
this.name=name;
this.age=age;
}
publicLonggetId(){
returnid;
}
publicvoidsetId(Longid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
}
ReflectTester类的copy(Objectobject)方法依次执行以下步骤:
(1)获得对象的类型:
ClassclassType=object.getClass();
System.out.println("Class:
"+classType.getName());
在java.lang.Object类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型。
Class类是ReflectionAPI中的核心类,它有以下方法:
getName():
获得类的完整名字;
getFields():
获得类的public类型的属性;
getDeclaredFields():
获得类的所有属性;
getMethods():
获得类的public类型的方法;
getDeclaredMethods():
获得类的所有方法;
getMethod(Stringname,Class[]parameterTypes):
获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型;
getConstructors():
获得类的public类型的构造方法;
getConstructor(Class[]parameterTypes):
获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型;
newInstance():
通过类的不带参数的构造方法创建这个类的一个对象;
(2)通过默认构造方法创建一个新对象:
ObjectobjectCopy=classType.getConstructor(newClass[]{}).newInstance(newObject[]{});
以上代码先调用Class类的getConstructor()方法获得一个Constructor对象,它代表默认的构造方法,然后调用Constructor对象的newInstance()方法构造一个实例。
(3)获得对象的所有属性:
Fieldfields[]=classType.getDeclaredFields();
Class类的getDeclaredFields()方法返回类的所有属性,包括public、protected、默认和private访问级别的属性。
(4)获得每个属性相应的getXXX()和setXXX()方法,然后执行这些方法,把原来对象的属性拷贝到新的对象中。
以上是一个反射(reflection)的比较详细的解说,当然真正工程上是不会这样麻烦的,这里是底层的讲解。
以下这个类运用反射机制调用其add()和echo()方法,代码如下:
Invoketester.java代码
importjava.lang.reflect.Method;
publicclassInvokeTester{
publicintadd(intparam1,intparam2){
returnparam1+param2;
}
publicStringecho(Stringmsg){
return"echo:
"+msg;
}
publicstaticvoidmain(String[]args)throwsException{
Class
>classType=InvokeTester.class;
ObjectinvokeTester=classType.newInstance();
//调用InvokeTester对象的add()方法
MethodaddMethod=classType.getMethod("add",newClass[]{int.class,
int.class});
Objectresult=addMethod.invoke(invokeTester,newObject[]{
newInteger(100),newInteger(200)});
System.out.println((Integer)result);
//调用InvokeTester对象的echo()方法
MethodechoMethod=classType.getMethod("echo",
newClass[]{String.class});
result=echoMethod.invoke(invokeTester,newObject[]{"Hello"});
System.out.println((String)result);
}
}
importjava.lang.reflect.Method;
publicclassInvokeTester{
publicintadd(intparam1,intparam2){
returnparam1+param2;
}
publicStringecho(Stringmsg){
return"echo:
"+msg;
}
publicstaticvoidmain(String[]args)throwsException{
Class
>classType=InvokeTester.class;
ObjectinvokeTester=classType.newInstance();
//调用InvokeTester对象的add()方法
MethodaddMethod=classType.getMethod("add",newClass[]{int.class,
int.class});
Objectresult=addMethod.invoke(invokeTester,newObject[]{
newInteger(100),newInteger(200)});
System.out.println((Integer)result);
//调用InvokeTester对象的echo()方法
MethodechoMethod=classType.getMethod("echo",
newClass[]{String.class});
result=echoMethod.invoke(invokeTester,newObject[]{"Hello"});
System.out.println((String)result);
}
}
add()方法的两个参数为int类型,获得表示add()方法的Method对象的代码如下:
MethodaddMethod=classType.getMethod("add",newClass[]{int.class,int.class});
Method类的invoke(Objectobj,Objectargs[])方法接收的参数必须为对象,如果参数为基本类型数据,必须转换为相应的包装类型的对象。
invoke()方法的返回值总是对象,如果实际被调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,再将其返回。
在本例中,尽管InvokeTester类的add()方法的两个参数以及返回值都是int类型,调用addMethod对象的invoke()方法时,只能