Java循环一个对象的所有属性,并通过反射给这些属性赋值/取值

说到循环遍历,最常见的遍历数组/列表、Map等。但是,在开发过程中,有时需要循环遍历一个对象的所有属性。遍历对象的属性该如何遍历呢?查了一下资料,需要用到一些反射的知识!

话不多说,先上代码

首先先定义一个测试对象 Test

public class Test {

    private String aa;

    private int bb;

    private String cc;

    public String dd;

    public String getAa() {
return aa;
} public void setAa(String aa) {
this.aa = aa;
} public int getBb() {
return bb;
} public void setBb(int bb) {
this.bb = bb;
} public String getCc() {
return cc;
} public void setCc(String cc) {
this.cc = cc;
}
}

这个对象里分别有aa bb cc 三个私有属性,dd一个公有属性,接下来通过反射来获取这个对象的四个属性值

    public static void main(String[] args) {

        /**
* 返回Class 对象所表示的类或接口的所有可访问公共字段。
*/
Field[] f1=Test.class.getFields();
System.out.println("Test类里面的公共字段属性的个数为:" +f1.length+"个,分别为:");
for(int i=0;i<f1.length;i++){
String attributeName=f1[i].getName();
System.out.println(attributeName);
} /**
* 返回 Class 对象所表示的类或接口所声明的所有字段,
* 包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。
*/
Field[] f=Test.class.getDeclaredFields();
System.out.println("Test类里面的所有字段属性的个数为:"+f.length+"个,分别为:");
for(int i=0;i<f.length;i++){
String attributeName=f[i].getName();
System.out.println(attributeName);
} }

运行main函数,输出如下:

Test类里面的公共字段属性的个数为:1个,分别为: 
dd 
Test类里面的所有字段属性的个数为:4个,分别为: 
aa 
bb 
cc 
dd

getFields()方法只能获取Test类里面的所有公有属性,getDeclaredFields()方法可获取Test类所有公有/私有属性。需要注意的是,如果Test类继承了别的类,这两个方法都无法获取父类里面的属性的。

现在,已经获取到了Test类里面的所有属性名,然后通过这些属性名给这个类的实例赋值和取值操作。

先来给实例赋值,代码如下:

        Test test=new Test();
//给test对象赋值
for(int i=0;i<f.length;i++){
//获取属相名
String attributeName=f[i].getName();
//将属性名的首字母变为大写,为执行set/get方法做准备
String methodName=attributeName.substring(0,1).toUpperCase()+attributeName.substring(1);
try{
//获取Test类当前属性的setXXX方法(私有和公有方法)
/*Method setMethod=Test.class.getDeclaredMethod("set"+methodName);*/
//获取Test类当前属性的setXXX方法(只能获取公有方法)
Method setMethod=Test.class.getMethod("set"+methodName,String.class);
//执行该set方法
setMethod.invoke(test,attributeName+"方法赋值");
}catch (NoSuchMethodException e) {
try {
Method setMethod=Test.class.getMethod("set"+methodName,int.class);
setMethod.invoke(test,123);
} catch (Exception e2) {
f[i].set(test,attributeName+"直接赋值");
} } }

如上代码,之前已经获取到了Test类里面的所有属性名,在这部分代码中,就可以通过属性名来获取与之对应的set方法。需要注意的是,在上面代码中try-catch了两次,是因为在Test这个类中的属性的set方法的参数,有的是String类型,有的是int类型的,还有的属性是没有set方法的。第一次try是未了抓取所有参数类型不是String类型和不存在的set方法。第二次抓取的是参数不是int类型的和不存在的set方法。依次进行处理。除此之外,假如set方法的参数类型还有更多的类型的话,可以通过Filed类的getGenericType() 这个方法先判断类型,这个以后再做赘述。

接下来从实例中通过get方法来取值,代码如下:

        //从test对象取值
for(int i=0;i<f.length;i++){
//获取属相名
String attributeName=f[i].getName();
//将属性名的首字母变为大写,为执行set/get方法做准备
String methodName=attributeName.substring(0,1).toUpperCase()+attributeName.substring(1);
Object result;
try{
//获取Test类当前属性的setXXX方法(私有和公有方法)
/*Method setMethod=Test.class.getDeclaredMethod("set"+methodName);*/
//获取Test类当前属性的setXXX方法(只能获取公有方法)
Method getMethod=Test.class.getMethod("get"+methodName);
//执行该set方法
result=getMethod.invoke(test); }catch(NoSuchMethodException e){
result=f[i].get(test);
}
System.out.println("属性:"+attributeName+"="+result);
}

这里的代码也try-catch一次,get方法不存在参数类型判断的,这里的try-catch只是为了抓取公有属性不存在get方法的情况以做相应的处理。

运行测试程序,输出结果如下:

属性:aa=aa方法赋值 
属性:bb=123 
属性:cc=cc方法赋值 
属性:dd=dd直接赋值

最后附上完整的测试程序

    public static void main(String[] args) throws Exception{

        /**
* 返回Class 对象所表示的类或接口的所有可访问公共字段。
*/
Field[] f1=Test.class.getFields();
System.out.println("Test类里面的公共字段属性的个数为:" +f1.length+"个,分别为:");
for(int i=0;i<f1.length;i++){
String attributeName=f1[i].getName();
System.out.println(attributeName);
} /**
* 返回 Class 对象所表示的类或接口所声明的所有字段,
* 包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。
*/
Field[] f=Test.class.getDeclaredFields();
System.out.println("Test类里面的所有字段属性的个数为:"+f.length+"个,分别为:");
for(int i=0;i<f.length;i++){
String attributeName=f[i].getName();
System.out.println(attributeName);
} Test test=new Test();
//给test对象赋值
for(int i=0;i<f.length;i++){
//获取属相名
String attributeName=f[i].getName();
//将属性名的首字母变为大写,为执行set/get方法做准备
String methodName=attributeName.substring(0,1).toUpperCase()+attributeName.substring(1);
try{
//获取Test类当前属性的setXXX方法(私有和公有方法)
/*Method setMethod=Test.class.getDeclaredMethod("set"+methodName);*/
//获取Test类当前属性的setXXX方法(只能获取公有方法)
Method setMethod=Test.class.getMethod("set"+methodName,String.class);
//执行该set方法
setMethod.invoke(test,attributeName+"方法赋值");
}catch (NoSuchMethodException e) {
try {
Method setMethod=Test.class.getMethod("set"+methodName,int.class);
setMethod.invoke(test,123);
} catch (Exception e2) {
f[i].set(test,attributeName+"直接赋值");
} } }
//从test对象取值
for(int i=0;i<f.length;i++){
//获取属相名
String attributeName=f[i].getName();
//将属性名的首字母变为大写,为执行set/get方法做准备
String methodName=attributeName.substring(0,1).toUpperCase()+attributeName.substring(1);
Object result;
try{
//获取Test类当前属性的setXXX方法(私有和公有方法)
/*Method setMethod=Test.class.getDeclaredMethod("set"+methodName);*/
//获取Test类当前属性的setXXX方法(只能获取公有方法)
Method getMethod=Test.class.getMethod("get"+methodName);
//执行该set方法
result=getMethod.invoke(test); }catch(NoSuchMethodException e){
result=f[i].get(test);
}
System.out.println("属性:"+attributeName+"="+result);
} }

Java循环一个对象的所有属性,并通过反射给这些属性赋值/取值的更多相关文章

  1. java使用反射给对象属性赋值的两种方法

    java反射无所不能,辣么,怎么通过反射设置一个属性的值呢? 主程序: /** * @author tengqingya * @create 2017-03-05 15:54 */ public cl ...

  2. Java中short、int、long、float、double的取值范围

    一.基本数据类型的特点,位数,最大值和最小值.1.基本类型:short 二进制位数:16 包装类:java.lang.Short 最小值:Short.MIN_VALUE=-32768 (-2的15此方 ...

  3. Java的8种基本数据类型的内存占用字节数和取值范围

    这是8中基本类型的内存中占用字节数(取值范围是2的(字节数X8-1)次方) 1.整型 类型 存储需求 bit数 取值范围 byte 1字节 1*8 -128-127 short 2字节 2*8 -32 ...

  4. SQL state [72000]; error code [1461]; ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值 ; nested exception is java.sql.BatchUpdateException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值

    本文转自  https://www.cnblogs.com/yingsong/p/5685790.html 原 因:某一个字段本为varchar2(1024),但是实际要插入的值超过varchar2允 ...

  5. 反射中的 Method 的 getReadMethod 与 getWriteMethod 使用 【获取一个对象的所有属性字段名称和其对应的值】

    转: class反射(一),以及Method 的 getReadMethod 与 getWriteMethod 使用 2018年11月28日 17:27:42 zich77521 阅读数 788   ...

  6. Java反射给泛型集合赋值

    Java反射给泛型集合赋值 泛型 Java泛型简单描述下: 比如创建一个List集合,我想在里边只放Student对象信息,就需要写成 List<Student> studentList ...

  7. [置顶] js中如何复制一个对象,如何获取所有属性和属性对应的值

    在js中如何复制一个对象,例如如下一个js对象. 如果知道这个对象的所有属性自然就可以重新new一个,然后对每个属性赋值,就可以做到,但如果不知道呢?如何创建一个内容相同 的对象呢? var obj= ...

  8. 乐字节Java循环:循环控制和嵌套循环

    乐字节小乐上次讲完了Java反射,接下来小乐给大家讲述Java循环. 循环有以下四部分: 一.循环控制 1. do..while 直到型 ( 先执行后判断) ,结构为: 先执行循环体,后判断布尔表达式 ...

  9. java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包

    首先自定义三个类 package reflection1; public interface MtInterface { void info(); } package reflection1; imp ...

随机推荐

  1. ubuntu预装的是vim tiny版本

    可以安装vim full版本,在full版本下键盘正常,安装好后同样使用vi命令.安装vim: ubuntu预装的是vim tiny版本,而需要的是vim full版本.执安装vim full版本:$ ...

  2. Spring 核心API

    BeanFactory: 这是一个工厂,用于生产任意Bean,采用延迟加载,第一次getBean时才会加载 ApplicationContext: 是BeanFactory的一个子接口,功能更强大(国 ...

  3. RDLC 主从报表筛选

    今天继续学习RDLC报表的“参数传递”及“主从报表” 一.先创建DataSet,如下图: 二.创建一个报表rptDEPT.rdlc,显示部门T_DPET的数据 三.嵌入Default.aspx中,写在 ...

  4. SQL中IN和EXISTS用法的区别

    结论 1. in()适合B表比A表数据小的情况 2. exists()适合B表比A表数据大的情况 当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用. select * fro ...

  5. poj1743

    题解: 后缀数组+二分答案 首先会发现这题实质上就是求最长不重复的相同子段 首先二分答案长度,之后对每一段信息进行维护 一段信息即保证这一段的sa值都大于mid即可 然后找到这段中后缀位置最大和最小处 ...

  6. 9.Django组件-cookie和session

    HTTP协议的无保存状态,对两次请求没有任何关联.每次请求都是相互独立的. 1.cookie简介 什么是会话跟踪技术我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会 ...

  7. 程序员之路:python3+PyQt5+pycharm桌面GUI开发(转)

    程序员之路:python3+PyQt5+pycharm桌面GUI开发 http://blog.sina.com.cn/s/blog_989218ad0102wz1k.html 先看效果: 图 1 没错 ...

  8. js算法初窥03(搜索及去重算法)

    前面我们了解了一些常用的排序算法,那么这篇文章我们来看看搜索算法的一些简单实现,我们先来介绍一个我们在实际工作中一定用到过的搜索算法——顺序搜索. 1.顺序搜索 其实顺序搜索十分简单,我们还是以第一篇 ...

  9. asp.net core模块学习

    一.配置管理 二.管道 三.认证与授权 四.MVCDemo 五.IdentityServer4 一.配置管理 1,读取内存配置 using System; using Microsoft.Extens ...

  10. 【随笔】Android应用市场搜索优化(ASO)

    参考了几篇网上的关于Android应用市场搜索优化(ASO)的分析,总结几点如下: 优化关键字:举例目前美团酒店在各Android市场上的关键字有“美团酒店.钟点房.团购.7天”等等,而酒店类竞对在“ ...