java反射机制详解.docx

上传人:b****6 文档编号:6566934 上传时间:2023-01-08 格式:DOCX 页数:11 大小:18.97KB
下载 相关 举报
java反射机制详解.docx_第1页
第1页 / 共11页
java反射机制详解.docx_第2页
第2页 / 共11页
java反射机制详解.docx_第3页
第3页 / 共11页
java反射机制详解.docx_第4页
第4页 / 共11页
java反射机制详解.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

java反射机制详解.docx

《java反射机制详解.docx》由会员分享,可在线阅读,更多相关《java反射机制详解.docx(11页珍藏版)》请在冰豆网上搜索。

java反射机制详解.docx

java反射机制详解

java反射机制详解

前言,在Java运行时刻,能否知道一个类的属性方法并调用改动之?

对于任意一个对象,能否知道他的所属类,并调用他的方法?

答案是肯定的。

这种动态的获取信息及动态调用方法的机制在Java中称为“反射”(reflection)。

Java反射机制主要提供以下功能:

在运行时判断任意一个对象所属的类;

在运行时构造任意一个类的对象;

在运行时判断任意一个类所具有的成员变量和方法;

在运行时调用任意一个对象的方法。

Reflection是Java被视为动态(或准动态)语言的一个关键性质。

这个机制允许程序在运行时透过ReflectionAPIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public,static等等)、superclass(例如Object)、实现之interfaces(例如Serializable),也包括fields和methods的所有信息,并可于运行时改变fields内容或调用methods。

一般而言,开发者社群说到动态语言,大致认同的一个定义是:

“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。

在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:

Class类:

代表一个类;

Field类:

代表类的成员变量(成员变量也称为类的属性);

Method类:

代表类的方法;

Constructor类:

代表类的构造方法;

Array类:

提供了动态创建数组,以及访问数组的元素的静态方法;

例程DateMethodsTest类演示了ReflectionAPI的基本作用,它读取命令行参数指定的类名,然后打印这个类所具有的方法信息,代码如下:

Datemethodstest.java代码

publicclassDateMethodsTest     

{     

publicstaticvoidmain(Stringargs[])throwsException     

{     

//加载并初始化命令行参数指定的类     

Class

>classType=Class.forName("java.util.Date");     

//获得类的所有方法     

Methodmethods[]=classType.getDeclaredMethods();     

for(inti=0;i

{     

System.out.println(methods[i].toString());     

}     

}     

}   

publicclassDateMethodsTest  

{  

publicstaticvoidmain(Stringargs[])throwsException  

{  

//加载并初始化命令行参数指定的类  

Class

>classType=Class.forName("java.util.Date");  

//获得类的所有方法  

Methodmethods[]=classType.getDeclaredMethods();  

for(inti=0;i

{  

System.out.println(methods[i].toString());  

}  

}  

例程ReflectTester类进一步演示了ReflectionAPI的基本使用方法。

ReflectTester类有一个copy(Objectobject)方法,这个方法能够创建一个和参数object同样类型的对象,然后把object对象中的所有属性拷贝到新建的对象中,并将它返回这个例子只能复制简单的JavaBean,假定JavaBean的每个属性都有public类型的getXXX()和setXXX()方法,代码如下:

Reflecttester.java代码

publicclassReflectTester{     

publicObjectcopy(Objectobject)throwsException{     

//获得对象的类型     

Class

>classType=object.getClass();     

System.out.println("Class:

"+classType.getName());     

//通过默认构造方法创建一个新的对象     

ObjectobjectCopy=classType.getConstructor(newClass[]{}).newInstance(newObject[]{});     

//获得对象的所有属性     

Fieldfields[]=classType.getDeclaredFields();     

for(inti=0;i

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;     

}     

}  

publicclassReflectTester{  

publicObjectcopy(Objectobject)throwsException{  

//获得对象的类型  

Class

>classType=object.getClass();  

System.out.println("Class:

"+classType.getName());  

//通过默认构造方法创建一个新的对象  

ObjectobjectCopy=classType.getConstructor(newClass[]{}).newInstance(newObject[]{});  

//获得对象的所有属性  

Fieldfields[]=classType.getDeclaredFields();  

for(inti=0;i

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()方法时,只能

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 中医中药

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1