黑马程序员技术交流社区
标题:
论反射的正确使用方式以及应用范围
[打印本页]
作者:
龙骑将杨影枫
时间:
2014-12-5 23:56
标题:
论反射的正确使用方式以及应用范围
假设有这么一个数据库表,用来记录一个月内每天的温度。又有一个名为MonthTemp的类,有30个属性,分别是day1,day2,day3,day4...一直到day30。
然后从表内取出1条记录,将它存在一个list内。请问为monthTemp的每一个属性赋值呢?
当然,简单但是麻烦的普通解决思路不是没有。我大可以写30条set,一个个把值存进去。问题是这样写起花时间,还容易写错。于是我准备文艺一点,使用反射。
首先,先建一个MonthTemp的类,为其加上30个属性。
package refi;
public class MonthTemp {
private int day1=0;
private int day2=0;
private int day3=0;
private int day4=0;
private int day5=0;
private int day6=0;
private int day7=0;
private int day8=0;
private int day9=0;
private int day10=0;
private int day11=0;
private int day12=0;
private int day13=0;
private int day14=0;
private int day15=0;
private int day16=0;
private int day17=0;
private int day18=0;
private int day19=0;
private int day20=0;
private int day21=0;
private int day22=0;
private int day23=0;
private int day24=0;
private int day25=0;
private int day26=0;
private int day27=0;
private int day28=0;
private int day29=0;
private int day30=0;
public int getDay1() {
return day1;
}
public void setDay1(int day1) {
this.day1 = day1;
}
public int getDay2() {
return day2;
}
public void setDay2(int day2) {
this.day2 = day2;
}
public int getDay3() {
return day3;
}
public void setDay3(int day3) {
this.day3 = day3;
}
public int getDay4() {
return day4;
}
public void setDay4(int day4) {
this.day4 = day4;
}
public int getDay5() {
return day5;
}
public void setDay5(int day5) {
this.day5 = day5;
}
public int getDay6() {
return day6;
}
public void setDay6(int day6) {
this.day6 = day6;
}
public int getDay7() {
return day7;
}
public void setDay7(int day7) {
this.day7 = day7;
}
public int getDay8() {
return day8;
}
public void setDay8(int day8) {
this.day8 = day8;
}
public int getDay9() {
return day9;
}
public void setDay9(int day9) {
this.day9 = day9;
}
public int getDay10() {
return day10;
}
public void setDay10(int day10) {
this.day10 = day10;
}
public int getDay11() {
return day11;
}
public void setDay11(int day11) {
this.day11 = day11;
}
public int getDay12() {
return day12;
}
public void setDay12(int day12) {
this.day12 = day12;
}
public int getDay13() {
return day13;
}
public void setDay13(int day13) {
this.day13 = day13;
}
public int getDay14() {
return day14;
}
public void setDay14(int day14) {
this.day14 = day14;
}
public int getDay15() {
return day15;
}
public void setDay15(int day15) {
this.day15 = day15;
}
public int getDay16() {
return day16;
}
public void setDay16(int day16) {
this.day16 = day16;
}
public int getDay17() {
return day17;
}
public void setDay17(int day17) {
this.day17 = day17;
}
public int getDay18() {
return day18;
}
public void setDay18(int day18) {
this.day18 = day18;
}
public int getDay19() {
return day19;
}
public void setDay19(int day19) {
this.day19 = day19;
}
public int getDay20() {
return day20;
}
public void setDay20(int day20) {
this.day20 = day20;
}
public int getDay21() {
return day21;
}
public void setDay21(int day21) {
this.day21 = day21;
}
public int getDay22() {
return day22;
}
public void setDay22(int day22) {
this.day22 = day22;
}
public int getDay23() {
return day23;
}
public void setDay23(int day23) {
this.day23 = day23;
}
public int getDay24() {
return day24;
}
public void setDay24(int day24) {
this.day24 = day24;
}
public int getDay25() {
return day25;
}
public void setDay25(int day25) {
this.day25 = day25;
}
public int getDay26() {
return day26;
}
public void setDay26(int day26) {
this.day26 = day26;
}
public int getDay27() {
return day27;
}
public void setDay27(int day27) {
this.day27 = day27;
}
public int getDay28() {
return day28;
}
public void setDay28(int day28) {
this.day28 = day28;
}
public int getDay29() {
return day29;
}
public void setDay29(int day29) {
this.day29 = day29;
}
public int getDay30() {
return day30;
}
public void setDay30(int day30) {
this.day30 = day30;
}
}
复制代码
当然按照我的性格,让我一个个敲这30个属性,那是做梦。于是在建立MonthTemp之前,我先写了一个偷懒的类。
package refi;
public class CreateMonth {
public static void main(String[] args) {
for(int i=0;i<30;i++){
System.out.println("private int day"+(i+1)+"=0;");
}
}
}
复制代码
运行,复制粘贴,搞定。
然后我创建了一个MonthTempMethods,用2个Map来保存MonthTemp的get和set方法。同时我取方法getDay1()的缩略day1为字符串,作为getDay方法的映射值扔进map中。这样我可以通过day1直接在map中寻找到getDay1()方法。
package refi;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.regex.Pattern;
public class MonthTempMethods {
static Class cls;
//用map保存标签tag和对应的方法
public static Hashtable<String,Method> getMethods= null;
public static Hashtable<String,Method> setMethods= null;
public static void init(){
getMethods = new Hashtable<String, Method>();
setMethods = new Hashtable<String, Method>();
cls = MonthTemp.class;
Method methods[] = cls.getMethods();
//定义正则表达式,只保留get和set方法
String gs = "get(\\w+)";
Pattern getM = Pattern.compile(gs);
String ss ="set(\\w+)";
Pattern setM = Pattern.compile(ss);
String temp = "$1";
String tag="";
for(int i = 0; i < methods.length; ++i) {
//获取方法
Method m = methods[i];
//获取方法名
String methodName = m.getName();
if (Pattern.matches(gs, methodName )) {//如果是get系方法就保存在get的Map里
tag = getM.matcher(methodName).replaceAll(temp).toLowerCase();
getMethods.put(tag, m);
}else {//否则就保存在set方法里
tag = setM.matcher(methodName).replaceAll(temp).toLowerCase();
setMethods.put(tag, m);
}
}
}
}
复制代码
然后我编写测试类Demo
package refi;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//初始化数组
List<Integer> temp=new ArrayList<Integer>();
for(int i=0;i<30;i++){
temp.add((int) (Math.random()*20+10));
}
//初始化MonthTemp里的get和set方法
MonthTempMethods.init();
//实例化一个MonthTemp
MonthTemp mt =new MonthTemp();
//赋值
for(int i=0;i<temp.size();i++){
String tag="day"+(i+1);
Method m=MonthTempMethods.setMethods.get(tag);
m.invoke(mt,temp.get(i));
}
//输出
for(int i=0;i<30;i++){
String tag="day"+(i+1);
Method m=MonthTempMethods.getMethods.get(tag);
System.out.println("第"+(i+1)+"天的温度是:"+m.invoke(mt));
}
}
}
复制代码
运行后如图:
QQ截图20141205234811.jpg
(70.89 KB, 下载次数: 8)
下载附件
2014-12-5 23:48 上传
顺利完成。
写在最后的废话:
其实这么一看,我写的代码比不写30次get和set多(于是2B的内核再次暴露了出来)。但是这么写有一个巨大的优势,以后如果我再取出一条MonthTemp数据来进行处理,就可以直接调用MonthTempMethods的方法了。MonthTemp在不同的程序中使用的越多,反射的优势就越大。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2