本文主要通过Java反射应用实例来讲解
利用反射方法创建对象(使用默认构造函数和自定义构造函数)
,访问对应对象的方法(包括带参数的和不带参数的),访问对应对象的域(Field)
.
 从
这里
可以下载到完整的java代码工程:
 ?
http://download.csdn.net/detail/hejiangtao/4011663
很多IOC等框架都使用反射来实现,例如Spring, Hibernate等, Java反射的方式实现的逻辑比普通类逻辑的效率是要差一些的(14至300倍左右), 具体可以参考我转载的一篇文章<java反射的性能问题
>http://blog.csdn.net/hejiangtao/article/details/7188835.
首先看下我们实例中被访问的类DataTypeBean.java:
这个Bean中定义了4种类型的Field,包含了int, 
String,String数组和List; 定义了默认构造函数和自定义的构造函数; 还有一个给List域赋值的带参数函数; 
一个不带参数的toString函数.我们要实现的就是使用反射的方法来访问这些Fields 和Methods.
?
[html]
 view plain
copy
- 
package?com.ross.reflect.bean;??
 
- 
import?java.util.*;??
 
- 
/**??
 
- 
?*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com??
 
- 
?*?Date:?2012-1-4??
 
- 
?*?Since:?MyJavaExpert?v1.0??
 
- 
?*?Description:?It?will?contains?some?typical?fields?whose?data?types??
 
- 
?*???are?using?frequently.?it?will?be?used?in?the?reflect?test??
 
- 
?*/??
 
- 
public?class?DataTypeBean??
 
- 
{??
 
- 
????private?int?iInt;??
 
- 
????private?String?sStr;??
 
- 
????private?String[]?saStr;??
 
- 
????List<
Integer
>
?oList;??
 
- 
??
 
- 
????//?default?constructor??
 
- 
????public?DataTypeBean()??
 
- 
????{??
 
- 
????}??
 
- 
??
 
- 
????//?constructor?with?parameters??
 
- 
????public?DataTypeBean(int?iInt,?String?sStr,?String[]?saStr,??
 
- 
????????????List<
Integer
>
?oList)??
 
- 
????{??
 
- 
????????this.iInt
?=?iInt;??
 
- 
????????this.saStr
?=?saStr;??
 
- 
????????this.sStr
?=?sStr;??
 
- 
????????this.oList
?=?oList;??
 
- 
????}??
 
- 
??
 
- 
????//?method?with?parameter,?it?will?set?value?of?the?list?field??
 
- 
????public?void?addDataToList(int?iStart,?int?iEnd)??
 
- 
????{??
 
- 
????????if?(iStart?<
?
iEnd
)??
 
- 
????????{??
 
- 
????????????oList
?=?
new
?ArrayList
<
Integer
>
();??
 
- 
????????????while?(iStart?<
=?iEnd)??
 
- 
????????????{??
 
- 
????????????????oList.add(iStart);??
 
- 
????????????????iStart++;??
 
- 
????????????}??
 
- 
????????}??
 
- 
????}??
 
- 
??
 
- 
????//?method?without?parameter??
 
- 
????public?String?toString()??
 
- 
????{??
 
- 
????????StringBuffer?sbStr
?=?
new
?StringBuffer();??
 
- 
????????sbStr.append("Values?of?the?fields?of?DataTypeBean:?iInt
?=?");??
 
- 
????????sbStr.append(this.iInt).append("?;?");??
 
- 
????????for?(int?i
?=?
0
;?i?
<
?
this.saStr.length
;?i++)??
 
- 
????????{??
 
- 
????????????sbStr.append("saStr").append("[").append(i).append("]").append(??
 
- 
????????????????????"?=?").append(saStr[i]).append("?;?");??
 
- 
????????}??
 
- 
??
 
- 
????????for?(int?j
?=?
0
;?j?
<
?
this.oList.size
();?j++)??
 
- 
????????{??
 
- 
????????????sbStr.append("oList.get").append("(").append(j).append(")").append(??
 
- 
????????????????????"?=?").append(oList.get(j)).append("?;?");??
 
- 
????????}??
 
- 
????????return?sbStr.toString();??
 
- 
????}??
 
- 
??
 
- 
????//省略了set/get方法??
 
- 
}??
 
来看我们的反射的实现类MyReflect.java, 由于担心代码太长不好看,就全部在Main函数里面写了,方便看.
1. 首先我们看下使用默认构造函数创建类对象, 并通过访问Field对象来给类对象赋值, 最后通过toString方法打印字符串.
初始化我们要使用的参数, 这些参数将用于给类的Field赋值:
[html]
 view plain
copy
- 
int?
iInt
?=?
2012
;??
 
- 
String?sStr
?=?
"This?a?string!"
;??
 
- 
String[]?saStr
?=?
new
?String[]?{?"First?item?of?the?string?array",??
 
- 
????????"Second?item?of?the?string?array",??
 
- 
????????"Third?item?of?the?string?array"?};??
 
- 
List<
Integer
>
?
oList
?=?
new
?ArrayList
<
Integer
>
();??
 
- 
??
 
- 
//?Initialize?the?oList??
 
- 
int?i
?=?
0
;??
 
- 
while?(i?<
?
3
)??
 
- 
{??
 
- 
????oList.add(i);??
 
- 
????i++;??
 
- 
}??
 
获取
DataTypeBean的类,和我们将要用到的方法对象, 其中toString方法是不带参数的,addDataToList则是带参数的. 由此可以看出我们在使用反射方法的时候是需要知道参数个数和参数类型的:
[html]
 view plain
copy
- 
//?get?class??
 
- 
Class?oClass
?=?Class.forName("com.ross.reflect.bean.DataTypeBean");??
 
- 
//?get?the?toString?method,?a?method?without?parameters??
 
- 
Method?oToStringMethod
?=?
oClass
.getMethod("toString");??
 
- 
//?get?the?addDataToList?method,?a?method?with?parameters??
 
- 
Method?oAddDataToListMethod
?=?
oClass
.getMethod("addDataToList",??
 
- 
????????int.class,?int.class);??
 
使用默认构造函数创建一个
DataTypeBean的对象:
[html]
 view plain
copy
- 
//?used?default?constructor?to?initialize?a?object??
 
- 
Object?oDefalutObject
?=?
oClass
.newInstance();??
 
使用反射方法访问Field来给对象赋值:
[html]
 view plain
copy
- 
//?access?fields?process,?getDeclaredFields?can?access?private?and??
 
- 
//?protected?fields??
 
- 
Field[]?oFields
?=?
oClass
.getDeclaredFields();??
 
- 
for?(int?j
?=?
0
;?j?
<
?
oFields.length
;?j++)??
 
- 
{??
 
- 
????//?to?access?the?private??
 
- 
????oFields[j].setAccessible(true);??
 
- 
??
 
- 
????//?getSimpleName?method?can?get?the?type?of?the?field,?according?the??
 
- 
????//?field?type?set?the?data?to?the?field??
 
- 
????if?("int".equals(oFields[j].getType().getSimpleName()))??
 
- 
????{??
 
- 
????????oFields[j].setInt(oDefalutObject,?iInt);??
 
- 
????}??
 
- 
????else?if?("String[]".equals(oFields[j].getType().getSimpleName()))??
 
- 
????{??
 
- 
????????oFields[j].set(oDefalutObject,?saStr);??
 
- 
????}??
 
- 
????else?if?("String".equals(oFields[j].getType().getSimpleName()))??
 
- 
????{??
 
- 
????????oFields[j].set(oDefalutObject,?sStr);??
 
- 
????}??
 
- 
????else?if?("List".equals(oFields[j].getType().getSimpleName()))??
 
- 
????{??
 
- 
????????oFields[j].set(oDefalutObject,?oList);??
 
- 
????}??
 
- 
}??
 
通过反射方法调用
DataTypeBean的toString方法将赋值后的
DataTypeBean打印出来:
[html]
 view plain
copy
- 
//?print?the?object??
 
- 
String?sBeanString
?=?(String)?oToStringMethod.invoke(oDefalutObject);??
 
- 
System.out??
 
- 
????????.println("the?string?of?the?object?created?by?defaut?constructor:?"??
 
- 
????????????????+?sBeanString);??
 
运行后,我们的控制台打印出如下信息:
[html]
 view plain
copy
- 
the?string?of?the?object?created?by?defaut?constructor:?Values?of?the?fields?of?DataTypeBean:?
iInt
?=?
2012
?;???
 
- 
saStr[0]?=?First?item?of?the?string?array?;?saStr[1]?=?Second?item?of?the?string?array?;?saStr[2]?=?Third?item???
 
- 
of?the?string?array?;?oList.get(0)?=?0?;?oList.get(1)?=?1?;?oList.get(2)?=?2?;???
 
2. 
我们再看下使用自定义构造函数创建类对象, 并通过带参数的函数给其List域赋值, 最后通过toString方法打印字符串.
变更下我们要用的参数, 好在控制台上跟默认构造函数创建的对象的打印信息做区分:
[html]
 view plain
copy
- 
//?initialize?the?parameters?for?customized?constructor,?the?oList?will??
 
- 
//?be?initialized?by?the?method?with?parameters??
 
- 
iInt
?=?
2013
;??
 
- 
sStr
?=?
"This?another?string!"
;??
 
- 
saStr
?=?
new
?String[]?{?"1st?item?of?the?string?array",??
 
- 
????????"2nd?item?of?the?string?array",?"3rd?item?of?the?string?array"?};??
 
- 
oList
?=?
new
?ArrayList
<
Integer
>
();??
 
使用自定义构造函数创建类对象:
[html]
 view plain
copy
- 
//?used?customized?constructor?to?initialize?a?object:?DataTypeBean(int??
 
- 
//?iInt,?String?sStr,?String[]?saStr,?List<
Integer
>
?oList)??
 
- 
Constructor?oCon
?=?
oClass
.getConstructor(int.class,?String.class,??
 
- 
????????String[].class,?List.class);??
 
- 
Object?oCustomizedObject
?=?
oCon
.newInstance(iInt,?sStr,?saStr,?oList);??
 
使用带参数的函数给List 域赋值:
[html]
 view plain
copy
- 
//Use?the?method?with?parameters?initialize?the?List?Object??
 
- 
?oAddDataToListMethod.invoke(oCustomizedObject,2013,2015);??
 
同样的,通过反射方法调用
DataTypeBean的toString方法将赋值后的
DataTypeBean打印出来:
[html]
 view plain
copy
- 
//?print?the?object??
 
- 
???????sBeanString
?=?(String)?oToStringMethod.invoke(oCustomizedObject);??
 
- 
???????System.out??
 
- 
???????????????.println("the?string?of?the?object?created?by?customized?constructor:?"??
 
- 
???????????????????????+?sBeanString);??
 
运行后,我们的控制台打印如下信息:
[html]
 view plain
copy
- 
the?string?of?the?object?created?by?customized?constructor:?Values?of?the?fields?of?DataTypeBean:?
iInt
?=?
2013
?;???
 
- 
saStr[0]?=?1st?item?of?the?string?array?;?saStr[1]?=?2nd?item?of?the?string?array?;?saStr[2]?=?3rd?item?of?the??
 
- 
?string?array?;?oList.get(0)?=?2013?;?oList.get(1)?=?2014?;?oList.get(2)?=?2015?;?oList.get(3)?=?2016?;???
 
为了方便参考,我将完整的MyReflect.java贴出来了:
?
[html]
 view plain
copy
- 
package?com.ross.reflect;??
 
- 
import?java.lang.reflect.Constructor;??
 
- 
import?java.lang.reflect.Field;??
 
- 
import?java.lang.reflect.InvocationTargetException;??
 
- 
import?java.lang.reflect.Method;??
 
- 
import?java.util.ArrayList;??
 
- 
import?java.util.List;??
 
- 
/**??
 
- 
?*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com??
 
- 
?*?Date:?2012-1-9??
 
- 
?*?Since:?MyJavaExpert?v1.0??
 
- 
?*?Description:?reflect?method?implementation?and?test??
 
- 
?*/??
 
- 
public?class?MyReflect??
 
- 
{??
 
- 
????/**??
 
- 
?????*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com??
 
- 
?????*?Date:?2012-1-9???
 
- 
?????*?Description:?Use?reflect?method?to?access?the?fields?and?methods?of?DataTypebean??
 
- 
?????*/??
 
- 
????public?static?void?main(String[]?args)?throws?ClassNotFoundException,??
 
- 
????????????SecurityException,?NoSuchMethodException,?InstantiationException,??
 
- 
????????????IllegalAccessException,?IllegalArgumentException,??
 
- 
????????????InvocationTargetException??
 
- 
????{??
 
- 
????????int?iInt
?=?
2012
;??
 
- 
????????String?sStr
?=?
"This?a?string!"
;??
 
- 
????????String[]?saStr
?=?
new
?String[]?{?"First?item?of?the?string?array",??
 
- 
????????????????"Second?item?of?the?string?array",??
 
- 
????????????????"Third?item?of?the?string?array"?};??
 
- 
????????List<
Integer
>
?
oList
?=?
new
?ArrayList
<
Integer
>
();??
 
- 
??
 
- 
????????//?Initialize?the?oList??
 
- 
????????int?i
?=?
0
;??
 
- 
????????while?(i?<
?
3
)??
 
- 
????????{??
 
- 
????????????oList.add(i);??
 
- 
????????????i++;??
 
- 
????????}??
 
- 
????????//?get?class??
 
- 
????????Class?oClass
?=?Class.forName("com.ross.reflect.bean.DataTypeBean");??
 
- 
????????//?get?the?toString?method,?a?method?without?parameters??
 
- 
????????Method?oToStringMethod
?=?
oClass
.getMethod("toString");??
 
- 
????????//?get?the?addDataToList?method,?a?method?with?parameters??
 
- 
????????Method?oAddDataToListMethod
?=?
oClass
.getMethod("addDataToList",??
 
- 
????????????????int.class,?int.class);??
 
- 
??
 
- 
????????//?used?default?constructor?to?initialize?a?object??
 
- 
????????Object?oDefalutObject
?=?
oClass
.newInstance();??
 
- 
??
 
- 
????????//?access?fields?process,?getDeclaredFields?can?access?private?and??
 
- 
????????//?protected?fields??
 
- 
????????Field[]?oFields
?=?
oClass
.getDeclaredFields();??
 
- 
????????for?(int?j
?=?
0
;?j?
<
?
oFields.length
;?j++)??
 
- 
????????{??
 
- 
????????????//?to?access?the?private??
 
- 
????????????oFields[j].setAccessible(true);??
 
- 
??
 
- 
????????????//?getSimpleName?method?can?get?the?type?of?the?field,?according?the??
 
- 
????????????//?field?type?set?the?data?to?the?field??
 
- 
????????????if?("int".equals(oFields[j].getType().getSimpleName()))??
 
- 
????????????{??
 
- 
????????????????oFields[j].setInt(oDefalutObject,?iInt);??
 
- 
????????????}??
 
- 
????????????else?if?("String[]".equals(oFields[j].getType().getSimpleName()))??
 
- 
????????????{??
 
- 
????????????????oFields[j].set(oDefalutObject,?saStr);??
 
- 
????????????}??
 
- 
????????????else?if?("String".equals(oFields[j].getType().getSimpleName()))??
 
- 
????????????{??
 
- 
????????????????oFields[j].set(oDefalutObject,?sStr);??
 
- 
????????????}??
 
- 
????????????else?if?("List".equals(oFields[j].getType().getSimpleName()))??
 
- 
????????????{??
 
- 
????????????????oFields[j].set(oDefalutObject,?oList);??
 
- 
????????????}??
 
- 
????????}??
 
- 
??
 
- 
????????//?print?the?object??
 
- 
????????String?sBeanString
?=?(String)?oToStringMethod.invoke(oDefalutObject);??
 
- 
????????System.out??
 
- 
????????????????.println("the?string?of?the?object?created?by?defaut?constructor:?"??
 
- 
????????????????????????+?sBeanString);??
 
- 
??
 
- 
????????//?initialize?the?parameters?for?customized?constructor,?the?oList?will??
 
- 
????????//?be?initialized?by?the?method?with?parameters??
 
- 
????????iInt
?=?
2013
;??
 
- 
????????sStr
?=?
"This?another?string!"
;??
 
- 
????????saStr
?=?
new
?String[]?{?"1st?item?of?the?string?array",??
 
- 
????????????????"2nd?item?of?the?string?array",?"3rd?item?of?the?string?array"?};??
 
- 
????????oList
?=?
new
?ArrayList
<
Integer
>
();??
 
- 
??
 
- 
????????//?used?customized?constructor?to?initialize?a?object:?DataTypeBean(int??
 
- 
????????//?iInt,?String?sStr,?String[]?saStr,?List<
Integer
>
?oList)??
 
- 
????????Constructor?oCon
?=?
oClass
.getConstructor(int.class,?String.class,??
 
- 
????????????????String[].class,?List.class);??
 
- 
????????Object?oCustomizedObject
?=?
oCon
.newInstance(iInt,?sStr,?saStr,?oList);??
 
- 
????????//Use?the?method?with?parameters?initialize?the?List?Object??
 
- 
????????oAddDataToListMethod.invoke(oCustomizedObject,2013,2015);??
 
- 
??????????
 
- 
????????//?print?the?object??
 
- 
????????sBeanString
?=?(String)?oToStringMethod.invoke(oCustomizedObject);??
 
- 
????????System.out??
 
- 
????????????????.println("the?string?of?the?object?created?by?customized?constructor:?"??
 
- 
????????????????????????+?sBeanString);??
 
- 
????}??
 
- 
}??
 
注:?转载请注明出处: http://hejiangtao.iteye.com
,?
用于商业得给我分成