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. SPLAY,LCT学习笔记(二)

    能够看到,上一篇的代码中有一段叫做find我没有提到,感觉起来也没有什么用,那么他的存在意义是什么呢? 接下来我们来填一下这个坑 回到我们的主题:NOI 2005维修数列 我们刚刚讨论了区间翻转的操作 ...

  2. 性能测试三:jmeter进阶之图形插件

    一.图形化插件的使用 使用Jmeter插件可以更直观的查看tps和响应时间 插件官网: http://jmeter-plugins.org/downloads/all 第一种方法,找到需要的插件下载j ...

  3. Javascript中的函数(三)

    一:概述 函数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解.JavaScript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的.通过函数对象的性质 ...

  4. 【C++ Primer 第13章】3. 交换操作

    交换操作 class HasPtr { friend void swap(HasPtr &rhs, HasPtr &yhs); //其他成员定义 }; void swap(HasPtr ...

  5. HTTP请求报文和响应报文

    HTTP请求报文 GET / HTTP/1.1 Host: www.baidu.com Connection: keep-alive Upgrade-Insecure-Requests: 1 User ...

  6. sdoi<序列计数>

    链接:https://www.luogu.org/problemnew/show/P3702 题解: 碰到计数题都要想想容斥 就跟碰到最大值最小要想想二分一样 考虑没有一个数是质数 那就确定了每一个数 ...

  7. 微信WebView关闭后本地cookie无法清除问题

    问题背景 在微信WebView下的页面中登录后,关闭WebView返回后再次进入页面,发现登录态还存在,原因是微信不会主动清除cookie以及其他的缓存. 期望是关闭窗口后会清除cookie,重新进入 ...

  8. free -m图解

  9. Django ORM OneToOneField

    一对一关系 一对一关系与多对一关系非常相似.如果你在模型中定义一个OneToOneField,该模型的实例将可以通过该模型的一个简单属性访问关联的模型. class Person(models.Mod ...

  10. Ajax提交form表单内容和文件(jQuery.form.js)

    jQuery官网是这样介绍form.js A simple way to AJAX-ify any form on your page; with file upload and progress s ...