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 }

 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 }

测试了一下性能:

 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     }

性能结果为:

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

感觉还行。呵呵

时间: 2024-10-31 00:16:23

Java:通过反射复制父类字段到子类。的相关文章

反射 通过父类获取所有子类

1 public void AddStates() 2 { 3 4 var subTypeQuery = from t in Assembly.GetExecutingAssembly().GetTypes() 5 where IsSubClassOf(t, typeof(State)) 6 select t; 7 8 foreach (var type in subTypeQuery) 9 { 10 var stateObj = Activator.CreateInstance(type) a

java父类引用指向子类对象

父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog.其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类. Animal animal = new Cat(); 即声明的是父类,实际指向的是子类的一个对象. 那这么使用的优点是什么,为什么要这么用?可以用这几个关键词来概括:多态.动态链接,向上转型 也有人说这是面向接口编程,可以降低程序的耦合性,即调用者不必关心调用的是哪个对象,只需要针对接口编程就可以了,被调用者对于调用者是完全透明的.让你更关

继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类。 (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法。 (3)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承。 (4)子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。 分析以上程

继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类. (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法.(3)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承.(4)子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承. 分析以上程序示例,主要疑惑点是“子类继承父类的成员变量,父类对象是否会实例化?私有成员变量是否会被继承?被继承的成员变量

Java父类对象调用子类实体:方法重写与动态调用

众所周知Java的handle和C++的ponter而不是object对应,我们很熟悉C++的父类pointer调用子类实体的例子,那么对于Java的handle是不是也可以这样呢? 这里我先给一个例子 class Father{ public void announce(){ System.out.println("Father"); } } class Child extends Father{ @Override public void announce(){ System.ou

java类继承总结一 父类类型与子类类型之间的转化问题(转)

java类继承总结一 父类类型与子类类型之间的转化问题 本文将通过一个实例描述父类类型与子类类型之间的转化问题,这个很特殊的问题常常会导致一些潜在的危险,让你整整一个晚上都在调试程序以解决一个让人抓狂的java.lang.ArrayStoreException异常. 1. 子类数组的引用可以装换为超类数组的引用 2. 子类的引用child可以转换为父类的引用parent(这里假设parent是父类对象,child是子类对象),但却不可以通过 parent调用child的特有方法 class Em

Java中父类强制转换为子类的可能

之前徒弟问了一个问题, 在Java中, 父类对象到底能不能转换成对应的子类对象? 到底能不能, 今天就来说说这个问题, 先看下面一段代码: package cn.com.hanbinit.test; /** * 检验父类是否可以强转为子类 * @author icer * */ public class ConvertPro extends Father { public static void main(String[] args) { Father father = new Father()

Java中不要在父类的构造方法中调用会被子类重写的方法

在Java中,不要在父类的构造函数中调用会被子类重写的方法,否则运行时会遇到意想不到的错误.看一个例子就会明白: import java.util.*; class Animal { public Animal() { eat(); } protected void eat() { System.out.println("Eat something"); } } public class Bird extends Animal { public Bird() { } @Override

java反射类的字段

java反射类的字段: package com.ma.reflection; import java.lang.reflect.Field; import org.junit.Test; import com.ma.bean.StudentBean; /** * 反射字段 * @author ma * */ public class Demo4 { /** * 反射公有字段 * @throws ClassNotFoundException * @throws NoSuchFieldExcepti

java 父类对象 和 子类对象 的类型转换

/** * 父类对象 和 子类对象 的类型转换 */ public class TypeCast{ public static void main(String[] args){ Employee[] staff = new Employee[3]; staff[0] = new Employee(); System.out.println(staff[0]); System.out.println(staff[1]); //Manager boss0 = staff[0]; //java.la