利用java反射机制,子类从父类拷贝属性--解决信息修改类设计的模式
用例场景:在一个商户管理系统中,操作人员对一个已注册的商户进行修改,这就触发了一个商户修改的工作流,修改提交后,修改的商户信息和原商户信息会传递到审核人员的窗口进行审核,审核完毕后,新商户信息更新,同时旧商户信息去到历史库。
数据库:我们这里有三张表——BusiInfo,BusiInfo_hist,BusiInfo_ba。BusiInfo是商户信息表存放经过注册的商户信息;BusiInfo_hist是商户信息历史表,将修改完成后的商户原信息保存到此处;BusiInfo_ba是商户信息在途表,保存并未审核通过的修改后信息,当审核通过后转移到_hist历史表,并将在途信息删除。
例子:比如商户信息为a,现在修改为b,我们看看各表中的数据如何变化。
修改前 修改中 修改后
BusiInfo a a b
BusiInfo_ba b
BusiInfo_hist a
好,现在我们开始编码,我们采用的是hibernate,通常的做法是每个表对应一个javabean,当信息在不同表中进行转移的时候,通常的做法是将先一个javabean中的信息一个一个getMessage(),然后再一个一个setMessage()到另一个javabean中。如果属性很多的话这是一个体力活,同时如果以后有新增属性的话,还要回来维护这个传值的方法。
我们决定找到一个一劳永逸的方法来解决这类问题。这里我们用到了java继承和反射机制。
Java代码 收藏代码
package com.mytesta;
/**
* 商户信息类,父类
*/
public class BusiInfoIn {
public String busiId;
public String busiLoginname;
public Long number;
public Long getNumber() {
return number;
}
public void setNumber(Long number) {
this.number = number;
}
public String getBusiId() {
return busiId;
}
public void setBusiId(String busiId) {
this.busiId = busiId;
}
public String getBusiLoginname() {
return busiLoginname;
}
public void setBusiLoginname(String busiLoginname) {
this.busiLoginname = busiLoginname;
}
}
Java代码 收藏代码
package com.mytesta;
/**
* 商户历史信息类,子类,同理可建立商户在途信息类
*
*/
public class BusiInfoIn_his extends BusiInfoIn {
public String deleteDate;
public String getDeleteDate() {
return deleteDate;
}
public void setDeleteDate(String deleteDate) {
this.deleteDate = deleteDate;
}
}
Java代码 收藏代码
package com.mytesta;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import junit.framework.TestCase;
public class BusiInfoTest extends TestCase {
public void test() throws Exception {
//
BusiInfoIn_his busiInfoIn_his=new BusiInfoIn_his();
busiInfoIn_his.setBusiId("1243124");
busiInfoIn_his.setBusiLoginname("jeffen");
busiInfoIn_his.setDeleteDate("2009-1-1");
BusiInfoIn busiInfo =new BusiInfoIn();
busiInfo=(BusiInfoIn)busiInfoIn_his;
System.out.println("子类传父类=============================");
System.out.println(busiInfo.getBusiId());
System.out.println(busiInfo.getBusiLoginname());
BusiInfoIn busiInfo2 =new BusiInfoIn();
busiInfo2.setBusiId("09090909");
busiInfo2.setBusiLoginname("runrun");
busiInfo2.setNumber(11L);
BusiInfoIn_his busiInfoIn_his2=new BusiInfoIn_his();
this.fatherToChild(busiInfo2, busiInfoIn_his2);
System.out.println("父类传子类=============================");
System.out.println(busiInfoIn_his2.getBusiId());
System.out.println(busiInfoIn_his2.getBusiLoginname());
System.out.println(busiInfoIn_his2.getNumber());
System.out.println(busiInfoIn_his2.getDeleteDate());
}
/*
* 将父类所有的属性COPY到子类中。
* 类定义中child一定要extends father;
* 而且child和father一定为严格javabean写法,属性为deleteDate,方法为getDeleteDate
*/
private void fatherToChild (Object father,Object child)throws Exception{
if(!(child.getClass().getSuperclass()==father.getClass())){
throw new Exception("child不是father的子类");
}
Class fatherClass= father.getClass();
Field ff[]= fatherClass.getDeclaredFields();
for(int i=0;i<ff.length;i++){
Field f=ff[i];//取出每一个属性,如deleteDate
Class type=f.getType();
Method m=fatherClass.getMethod("get"+upperHeadChar(f.getName()));//方法getDeleteDate
Object obj=m.invoke(father);//取出属性值
f.set(child,obj);
}
}
/**
* 首字母大写,in:deleteDate,out:DeleteDate
*/
private String upperHeadChar(String in){
String head=in.substring(0,1);
String out=head.toUpperCase()+in.substring(1,in.length());
return out;
}
}
我们可以看到子类比父类多了一个属性deleteDate,代表进入历史表的时间。上面的运行结果如下
Java代码 收藏代码
子类传父类=============================
1243124
jeffen
父类传子类=============================
09090909
runrun
11
null
可以看到只要我们的持久类采用标准的javabean格式,子类从父类拷贝属性信息一步完成,而且不受以后属性增减的影响。
分享到:
相关推荐
java反射获取所有属性,获取所有get方法,包括子类父类,以及包括List集合类
继承而得到的类称为子类,被继承的类称为父类。子类不能继承父类中访问权限为private的成员变量和方法,子类可以重写父类的方法,及命名与父类同名的成员变量。 子类通过隐藏父类的成员变量和重写父类的方法,把...
•子类扩展了父类,将可以获得父类的全部属性和方法,但不能获得父类构造器 •Java里的继承都是单继承,也就是只能有一个直接的父类,可以有n个间接父类。 重写父类的方法 •方法的重写要遵循“两同两...
2:继承:子类继承父类,子类可以拥有父类中已定义的方法,并且子类可以修改父类中的方法使其更适合特殊需求。 3:多台:不同对象对统一消息作出不同响应称之为多态 4:抽象:忽略与当前主题无关的那些方面,将...
用抽象类和多态的方式实现一个俄罗斯方块... 抽象类直接调用静态子类,子类调用返回值是二维数组的静态方法,然后用二维数组接收这个值。 5.最后也是一个难点,利用三重循环打印俄罗斯方块图形,把array当作形参传进去
用抽象类和多态的方式实现一个俄罗斯方块... 抽象类直接调用静态子类,子类调用返回值是二维数组的静态方法,然后用二维数组接收这个值。 5.最后也是一个难点,利用三重循环打印俄罗斯方块图形,把array当作形参传进去
B) 子类继承父类,那么子类可以重写父类的方法,但是一旦重写父类方法后,无法通过子类访问到父类的该方法。 C) 子类继承父类,如果父类中只有一个构造方法并且有参数,那么在子类的构造方法中必须先用super调用父类...
1.16. 获得方法的执行结果 25 1.17. 处理错误 26 第二章. 自定义类 29 2.0. 简介 29 2.1. 创建自定义类 30 2.2. 类的保存 32 2.3. 创建成员属性 33 2.4. 创建静态方法或属性 35 2.5. 创建子类 35 2.6. 覆盖父类方法 ...
修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被...
76. 如何在子类中调用父类方法的程序代码 292 77. 如何屏蔽子类对其父类的自动继承 293 78. 如何让表单设计器使用自定义表单类 296 79. 如何设计能正确显示和存储下拉列表中不存在选项的组合框类 297 80. 如何...
重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,...
Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface)是抽象类的变体。在接口中,所有方法...
each循环查看集合元素时只能获得元素的值,不能改变元素 2、类和对象初始化过程: 类:父类->子类,静态方法->静态代码块 对象:父类->子类,方法->代码块/显示赋值变量->构造器 3、线程相关知识: (1)进程是一个...
在构造子类对象时,会自动调用父类的构造函数,此时在父类的构造函数中的this指针所指向的是子类对象地址 10、AfxWinMain函数 MFC程序的WinMain函数是通过调用AfxWinMain函数来完成它的功能的 注:Afx前缀的函数代表...
即一个子类不能拥有两个或以上 的父类。 3、包 、包的定义 在Java中,把相关的代码组织到一起,称为"包"。包市一种将相关类、接口或其他包 组织起来的集合体,目的是为了将包含类代码的文件组织起来,易于查找和使用...
即一个子类不能拥有两个或以上 的父类。 3、包 、包的定义 在Java中,把相关的代码组织到一起,称为"包"。包市一种将相关类、接口或其他包 组织起来的集合体,目的是为了将包含类代码的文件组织起来,易于查找和使用...
即一个子类不能拥有两个或以上 的父类。 3、包 、包的定义 在Java中,把相关的代码组织到一起,称为"包"。包市一种将相关类、接口或其他包 组织起来的集合体,目的是为了将包含类代码的文件组织起来,易于查找和使用...
// 必须通过super调用父类当中的构造函数 super(context, DataBaseName, factory, version); } public DataBaseHelper(Context context) { super(context, DataBaseName, null, VERSION); } // 其实是调用...
3. 超出数组边界的表达式索引值同样不可访问。 4. C# 中没有全局变量或全局函数,取而代之的是通过静态函数和静态变量完成的。 数据类型 所有 C# 的类型都是从 object 类继承的。有两种数据类型: 1. 基本/内建...