有些时候需要建立子类继承于父类,尤其是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