Java:通过反射复制父类字段到子类。

Posted 寻梦人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java:通过反射复制父类字段到子类。相关的知识,希望对你有一定的参考价值。

有些时候需要建立子类继承于父类,尤其是java里面很多类是用mybatis generator生成的。通过父类构造子类,好像很麻烦,要逐个字段进行赋值(反正我没有找到其他好办法)。

想到用反射复制的方式来实现。通过研究,做到了。主要是用了fastjson里面的东西。估计已经有其他类库实现了这个功能,可惜我不知道,只能自己搞。

  

 

 1 import java.beans.Statement;
 2 import java.lang.reflect.Field;
 3 import java.lang.reflect.Method;
 4 import java.lang.reflect.Type;
 5 import java.util.List;
 6 
 7 import com.alibaba.fastjson.JSON;
 8 import com.alibaba.fastjson.util.DeserializeBeanInfo;
 9 import com.alibaba.fastjson.util.FieldInfo;
10 import com.alibaba.fastjson.util.TypeUtils;
11 
12 /**
13  * Created by fenggqc on 2016/6/29.
14  */
15 public class Copyer {
16 
17 
18     public static <B, S extends B>  void Copy(B bo, S so) throws IllegalAccessException {
19 
20         try {
21             Class bc = bo.getClass();
22             if (bo == null || so == null) {
23                 return;
24             }
25 
26 
27             DeserializeBeanInfo deserializeBeanInfo = DeserializeBeanInfo.computeSetters(so.getClass(), (Type) so.getClass());
28             List<FieldInfo> getters = TypeUtils.computeGetters(bo.getClass(), null);
29 
30             List<FieldInfo> setters = deserializeBeanInfo.getFieldList();
31             Object v;
32             FieldInfo getterfield;
33             FieldInfo setterfidld;
34 
35             for (int j = 0; j < getters.size(); j++) {
36 
37                 getterfield=getters.get(j);
38                 for (int i = 0; i < setters.size(); i++) {
39                     setterfidld=setters.get(i);
40 //                    System.out.println(setterfidld.getName());
41 //                    System.out.println(getterfield.getName());
42 
43                     if (setterfidld.getName().compareTo(getterfield.getName()) == 0) {
44                         v = getterfield.getMethod().invoke(bo);
45                        setterfidld.getMethod().invoke(so,v);
46                         break;
47                     }
48 
49                 }
50             }
51         } catch (Exception ex) {
52             System.out.println(ex.toString());
53         }
54 
55 
56     }
57 
58 
59 }
View Code

 

 1 public class SubClass extends  BaseClass {
 2 
 3     private Date birthday;
 4 
 5 
 6     public Date getBirthday() {
 7         return birthday;
 8     }
 9 
10     public void setBirthday(Date birthday) {
11         this.birthday = birthday;
12     }
13 }
14 
15 
16 public class BaseClass {
17 
18     private  Integer i;
19     private Boolean b;
20 
21     private  Boolean is;
22     private  Boolean isa;
23 
24     private  String whatname;
25 
26 
27     public Boolean getB() {
28         return b;
29     }
30 
31     public void setB(Boolean b) {
32         this.b = b;
33     }
34 
35     public Integer getI() {
36         return i;
37     }
38 
39     public void setI(Integer i) {
40         this.i = i;
41     }
42 
43     public Boolean getIs() {
44         return is;
45     }
46 
47     public void setIs(Boolean is) {
48         this.is = is;
49     }
50 
51     public Boolean getIsa() {
52         return isa;
53     }
54 
55     public void setIsa(Boolean isa) {
56         this.isa = isa;
57     }
58 
59     public String getWhatname() {
60         return whatname;
61     }
62 
63     public void setWhatname(String whatname) {
64         this.whatname = whatname;
65     }
66 }
View Code

 

 

 

测试了一下性能:

 1    @Test
 2     public void Test() throws InvocationTargetException, IllegalAccessException {
 3 
 4 
 5         BaseClass baseClass = new BaseClass();
 6         SubClass subClass=new SubClass();
 7 
 8         baseClass.setB(true);
 9         baseClass.setI(1010);
10         baseClass.setIs(false);
11         baseClass.setWhatname("fgq");
12 
13 
14         Integer i=0;
15         List<Integer> ii=new ArrayList<Integer>();
16         ii.add(1);
17         ii.add(10);
18         ii.add(100);
19         ii.add(1000);
20         ii.add(10000);
21 
22         StopWatch stopWatch=new StopWatch();
23 
24         stopWatch.reset();;
25         stopWatch.start();
26         Copyer.Copy(baseClass, subClass);
27         stopWatch.stop();
28         System.out.println("cache the reflection:"+String.valueOf(stopWatch.getTime()));
29 
30 
31 
32 
33         for (int j = 0; j < ii.size(); j++) {
34             i=0;
35             stopWatch.reset();;
36             stopWatch.start();
37             while ( i<ii.get(j)) {
38 
39                 Copyer.Copy(baseClass, subClass);
40                 subClass.setBirthday(new Date());
41                 i+=1;
42             }
43             stopWatch.stop();
44             System.out.println(String.format("%s  %s",ii.get(j),String.valueOf(stopWatch.getTime())));
45         }
46 
47 
48 
49 
50         System.out.println(JSON.toJSONString(subClass,SerializerFeature.PrettyFormat,SerializerFeature.UseISO8601DateFormat));
51 
52 
53     }
View Code

 

性能结果为:

cache the reflection:120
1 1
10 7
100 53
1000 139
10000 634

感觉还行。呵呵

以上是关于Java:通过反射复制父类字段到子类。的主要内容,如果未能解决你的问题,请参考以下文章

通过反射访问父类的私有成员

[解决方法] Java-Class.forName() 反射/映射子类 并转化为父类/接口

Java反射 - 2(对象复制,父类域)

java反射获取属性值

java 反射 , 判断Class是否是某个类的子类或父类

.net 父类值赋给子类