利用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格式,子类从父类拷贝属性信息一步完成,而且不受以后属性增减的影响。
分享到:
相关推荐
- 子类继承父类后,将自动获得所有非私有(public或protected)成员,包括属性、方法和事件。 2. **WPF中的UI元素继承** - WPF的UI元素类层次结构是基于`System.Windows.UIElement`和`System.Windows....
在标题和描述中提到的知识点主要集中在如何通过反射获取类的所有属性和get方法,包括来自子类和父类的。下面将详细介绍这些内容。 1. **获取所有属性**: 在Java中,`java.lang.Class` 类提供了获取类属性的方法。...
通过这种方式,`BmsNetUtil`的构造函数会先执行`HttpUtil`的构造函数,确保父类的数据成员得到正确初始化,然后再执行子类自己的初始化逻辑。 在C++中,如果子类没有显式地调用父类的构造函数,编译器会自动调用...
这可以通过`super`关键字来实现,确保父类的状态在子类实例化之前得到初始化。例如: ```java public class Parent { public Parent(int value) { // 初始化父类的成员 } } public class Child extends Parent ...
如果子类没有定义构造函数,它将自动获得一个默认构造函数,但仍然可以调用父类的构造函数。选项A错误,B正确,C错误,D错误。子类构造函数通常通过`super`关键字调用父类的构造函数。 4. **继承语法**:表示B继承...
这有助于确保父类的状态在子类实例化时得到正确的初始化。例如: ```java class Animal { Animal() { System.out.println("动物被创建"); } } class Dog extends Animal { Dog() { super(); // 显式调用父类的...
- 子类指的是通过继承关系得到的新类,比如正方形继承自长方形,但是从行为的角度看,正方形并不是长方形的子类型。 - 子类型强调的是子类与父类具有相同的行为能力,即子类的实例可以替换父类实例而不影响程序的...
1. **子类继承父类就拥有了父类的属性和方法**:当一个类(子类)继承另一个类(父类)时,子类自动获得了父类的所有非私有的成员变量和成员方法,这种机制极大地提高了代码的复用性和维护性。 2. **父类的构造...
方法覆盖要求子类方法与父类方法有相同的名称、返回类型和参数列表,并且子类方法必须使用`@Override`注解来明确表示它是对父类方法的覆盖。 总的来说,Swarm for Java在经济学仿真的应用结合了Java编程语言的高级...
而parent关键字则用于在子类中调用父类的方法,它允许子类覆盖父类的方法后仍能访问到父类的原始实现。如例10.13所示,子类`OtherClass`的`myFunc`方法调用了`parent::myFunc()`,这样就能够在执行子类方法的同时...
- 构造器:子类构造器在创建对象时会调用父类的构造器(除非显式指定),确保父类的状态得到初始化。 这些特性在实际编程中具有重要的意义,它们使得代码可重用性增强,结构更清晰,同时也支持复杂的设计模式和抽象...
6. **继承**:子类继承父类,可以获得父类的非私有属性和方法;父类通常称为超类或基类,子类则继承了父类的特性。 7. **封装**:通过访问控制符(public, private, default, protected)限制类的成员(字段和方法...
在题目中,Person p = new Child(),输出p.name会得到Person的name值,即"Person"。 9. 子类和父类属性的访问: - 子类对象可以访问父类的非私有属性。在Child类中,虽然grade字段是public的,但在main方法中直接...
在继承中,子类可以继承父类的属性,初始值为父类中该属性的初值,子类不能直接访问父类中非private的属性,但可以通过调用父类的public方法访问private属性。子类可以继承父类的成员方法,但无法直接访问父类的...
子类在继承父类时会获得所有非私有的成员变量和方法,但不继承构造方法。在创建子类对象时,如果子类构造方法中没有显式调用父类构造器,Java编译器会自动添加一个调用父类无参数构造器的super()语句。 其次,方法...
题目中,子类Test的构造函数覆盖了父类的成员变量name,所以new Test("Jack")创建的对象t.name的值是"Jack"。 9. 静态方法与实例变量:静态方法属于类,不依赖于特定的对象实例,因此不能直接访问非静态的类成员...
- 当父类发生变更时,所有继承自该父类的子类也可能受到影响。 - 从父类继承的实现无法在运行时改变。 ##### 3. Coad规则 为了合理使用继承,Coad提出了以下规则: - **"是一个…的特殊类型"**:子类应表达出它是...
因此,表达式`a /= SQR(k+m)/SQR(k+m)`等同于`a /= (k+m)*(k+m)/(k+m)*(k+m)`,简化后得到`a /= 1`,最终`a`的值为1。 第五题讨论了`const`关键字在指针声明中的不同用法。`(1)const char *p`表示`p`是一个指针,...
- 子类继承父类,可以获得父类的非私有成员。 - 子类覆盖(Override)父类方法时,访问修饰符不能更严格。 11. **方法的重载(Overloading)**: - 同一类中,方法名相同但参数列表不同的方法称为重载方法。 - ...
1. JavaScript 获取两数较大值:在JavaScript中,使用Math.max()函数可以获得两个数中的较大值,因此选项A是正确的。 2. FTP文件传输:FTP(File Transfer Protocol)是一种用于在网络上进行文件传输的标准协议。...