本文主要通过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
,?
用于商业得给我分成