Java反射 - 2(对象复制,父类域,内省)
为什么要复制对象?假设有个类Car,包含name,color2个属性,那么将car1对象复制给car2对象,只需要car2.setName(car1.getName)与car2.setColor(car1.getColor)两部操作即可。
实际项目中有很多类都有超过几十个,甚至上百个字段,这时如果采用以上方式,将会有很大的代码工作量与重复劳动。解决方法是使用反射机制。
首先有2个类如下
/**
* Created by yesiming on 16-11-19.
*/
public class Car {
private String name;
private String color;
// 省略set/get
}
}
/**
* Created by yesiming on 16-11-20.
*/
public class Kia extends Car{
private String model;
// 省略set/get
}
我们先操作入职Kia的域
/**
* 通过反射进行对象复制(漏洞:不能复制父类中的域)
* @throws Exception
*/
@Test
public void copyObject() throws Exception{
User src = new User(); // 源对象
src.setId(1);
src.setName("yesiming");
User target = new User(); // 目标对象
Class clazz = User.class;
Field[] fields = clazz.getDeclaredFields(); // 得到该类声明的域(不包含父类的域)
for(Field field : fields) {
if(!field.isAccessible())
field.setAccessible(true); // 设置可访问
field.set(target, field.get(src)); // 从源对象get值set到目标对象
}
// 输出显示
for(Field field : fields) {
System.out.println(field.get(target));
}
}
由于getDeclaredFields方法不能得到超类中的域,所以上述操作有缺陷,甚至不具有实际意义
下面是如何得到超类中的域,使用递归即可
/**
* 输出所有域,包括父类中的域(通过递归实现)
*/
public void showAllField(Class clazz) {
Field[] fields = clazz.getDeclaredFields();
System.out.println("------" + clazz.toString() + "------");
if(fields != null && fields.length > 0) {
for(Field field : fields) {
System.out.println(field);
}
}
Class superClazz = clazz.getSuperclass();
if(superClazz != Object.class) { // 结束递归
showAllField(superClazz); // 递归
}
} @Test
public void showAllFieldTest() {
Class clazz = Kia.class;
showAllField(clazz);
}
运行结果如下:
------class o1.o1_a.Kia------
private java.lang.String o1.o1_a.Kia.model
------class o1.o1_a.Car------
private java.lang.String o1.o1_a.Car.name
private java.lang.String o1.o1_a.Car.color
那么好,结合上述2种操作,就能写出具有实用价值的类复制方法了吗?
当然不是,Java中操作Bean的专业户是内省,Introspector
/**
* 通过专业操作JavaBean的内省,Introspector复制有继承的类
* @throws Exception
*/
@Test
public void showProfile() throws Exception { Kia k1 = new Kia(); // 源对象,继承自Car
k1.setName("起亚"); // 这是Car中的域
k1.setColor("白色"); // 这是Car中的域
k1.setModel("K4");
Kia k2 = new Kia(); // 目标对象 BeanInfo beanInfo = Introspector.getBeanInfo(Kia.class); // 得到Kia的Bean信息
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); //通过BeanInfo得到域的描述符
for (PropertyDescriptor pd : pds) {
if (pd.getName() == "getClass()") {
continue;
}
if (pd.getReadMethod() == null || pd.getWriteMethod() == null) { // 如果set, get不配对就不复制
continue;
}
// 反射set目标对象中的域
pd.getWriteMethod().invoke(k2, pd.getReadMethod().invoke(k1));
}
System.out.println(k2.getName() + k2.getModel() + k2.getColor());
}
Java反射 - 2(对象复制,父类域,内省)的更多相关文章
- Java 反射 Class对象
Java 反射 Class对象 @author ixenos 关键字:RTTI.动态绑定.动态加载.获得Class引用.泛型Class引用.newInstance的坑.JVM中的泛型类型信息 RTTI ...
- 【译】2. Java反射——Class对象
原文地址:http://tutorials.jenkov.com/java-reflection/classes.html ====================================== ...
- Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别
Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别 在工作中遇到一个问题,就是你需要去判断某个字符串是不是对象的某个成员属性名,然后根据判断结果 ...
- java 反射,注解,泛型,内省(高级知识点)
Java反射 1.Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs 取得任何一个已知名称的class的内部信息, 包括 ...
- java反射构建对象和方法的反射调用
Java反射技术应用广泛,其能够配置:类的全限定名,方法和参数,完成对象的初始化,设置是反射某些方法.可以增强java的可配置性. 1.1 通过反射构建对象(无参数): 例如我们使用 ReflectS ...
- Java反射获取对象VO的属性值(通过Getter方法)
有时候,需要动态获取对象的属性值. 比如,给你一个List,要你遍历这个List的对象的属性,而这个List里的对象并不固定.比如,这次User,下次可能是Company. e.g. 这次我需要做一个 ...
- 第五课 JAVA反射获取对象属性和方法(通过配置文件)
Service1.java package reflection; public class Service1 { public void doService1(){ System.out.print ...
- 用Java反射输出对象的所有属性的值
获取对象的类类型 Class cls = obj.getClass(); 用类类型获取属性数组 getFields()获取的是共有属性 getDeclaredFields()可以获取所有属性 Fiel ...
- 第五课 JAVA反射获取对象属性和方法
package com.hero; import java.lang.reflect.Field; public class TestReflction5 { public static void m ...
随机推荐
- UI基础 - UITabBarController
self.window = [[UIWindow alloc] init]; self.window.frame = [UIScreen mainScreen].bounds; oneViewCont ...
- codevs 2152 滑雪
2152 滑雪 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description trs喜欢滑雪.他来到了一个滑雪场,这个滑雪场 ...
- 转:zookeeper3.4.5安装笔记
文章来自于:http://mmicky.blog.163.com/blog/static/150290154201392893623943/ 1:解压 官网zookeeper.apache.org ...
- API Hook完全手册
文章来源: http://blog.csdn.net/atfield 原文作者: ATField 整理日期: 2008-07-16 发表评论 字体大小: 小 中 大 注:本文是根据我两年前写的一个 ...
- 使用 FreeMarker 替换 JSP 的 10 个理由
你还在使用 Java 服务器页面(俗称JSP)吗?我曾经也是,但是几年前我抛弃了它们,并且再也没有用过JSP了.JSP 是个很好的概念,但是它却剥夺了 web 开发的乐趣. 对我而言,这些都是小事,比 ...
- js的简单模板解析
在编程中总是会遇见很多动态生成的东西,一般我们都是通过简单的html拼接起来的 function createHtml(name, phone, addr, email, imageSrc){ var ...
- Highcharts下载与使用_数据报表图
Highcharts简介 Highcharts:功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯js图表库 Highcharts是一款纯javascript编写的图表库,能够很简单便捷的在Web ...
- angular 按需加载
angular.module('app',[]) .controller('ctrl',function ($http,$scope){ //ctrl控制器,名称作用的范围 html中ng-cont ...
- uva 12253 - Simple Encryption(dfs)
题目链接:uva 12253 - Simple Encryption 题目大意:给定K1.求一个12位的K2,使得KK21=K2%1012 解题思路:按位枚举,不且借用用高速幂取模推断结果. #inc ...
- web服务交互中HTTP数据内容GZIP,ZLIB格式压缩与解压缩封装(共享)
点击下载独立的dll //dll内部封装API格式 //gzip BOOL fnZlibDecompressPacket (__IN_PARAM unsigned char* gZlibDataBuf ...