Java循环一个对象的所有属性,并通过反射给这些属性赋值/取值
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循环一个对象的所有属性,并通过反射给这些属性赋值/取值的更多相关文章
- java使用反射给对象属性赋值的两种方法
java反射无所不能,辣么,怎么通过反射设置一个属性的值呢? 主程序: /** * @author tengqingya * @create 2017-03-05 15:54 */ public cl ...
- Java中short、int、long、float、double的取值范围
一.基本数据类型的特点,位数,最大值和最小值.1.基本类型:short 二进制位数:16 包装类:java.lang.Short 最小值:Short.MIN_VALUE=-32768 (-2的15此方 ...
- Java的8种基本数据类型的内存占用字节数和取值范围
这是8中基本类型的内存中占用字节数(取值范围是2的(字节数X8-1)次方) 1.整型 类型 存储需求 bit数 取值范围 byte 1字节 1*8 -128-127 short 2字节 2*8 -32 ...
- 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允 ...
- 反射中的 Method 的 getReadMethod 与 getWriteMethod 使用 【获取一个对象的所有属性字段名称和其对应的值】
转: class反射(一),以及Method 的 getReadMethod 与 getWriteMethod 使用 2018年11月28日 17:27:42 zich77521 阅读数 788 ...
- Java反射给泛型集合赋值
Java反射给泛型集合赋值 泛型 Java泛型简单描述下: 比如创建一个List集合,我想在里边只放Student对象信息,就需要写成 List<Student> studentList ...
- [置顶] js中如何复制一个对象,如何获取所有属性和属性对应的值
在js中如何复制一个对象,例如如下一个js对象. 如果知道这个对象的所有属性自然就可以重新new一个,然后对每个属性赋值,就可以做到,但如果不知道呢?如何创建一个内容相同 的对象呢? var obj= ...
- 乐字节Java循环:循环控制和嵌套循环
乐字节小乐上次讲完了Java反射,接下来小乐给大家讲述Java循环. 循环有以下四部分: 一.循环控制 1. do..while 直到型 ( 先执行后判断) ,结构为: 先执行循环体,后判断布尔表达式 ...
- java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包
首先自定义三个类 package reflection1; public interface MtInterface { void info(); } package reflection1; imp ...
随机推荐
- php数据类型之自动转换和强制转换
PHP在PHP 5.x阶段都是完全的弱类型的编程语言.所谓弱类型,就是在声明变量的时候,不需要指定变量的类型.我要声明一个整型的变量,我不用在前面非得写上类型,再写变量.而PHP 7 的性能有很大的提 ...
- 步步为营-72-asp.net简单练习(通过webForm实现一些简单实例)
WebForm成功之处在于:实现的代码后置,和asp相比实现了html代码和C#代码分离.但 aspx和aspx.cs之间的强耦合和性能方面(特别是服务器控件)做的不是很好. 参照步步为营-68完成相 ...
- Android Handler的内存泄露问题+解决方案
谈谈handler的内存泄露问题 再来看看我们的新建Handler的代码: private Handler mHandler = new Handler() { @Override public vo ...
- HDU 1075 字符串映射(map)
Sample InputSTARTfrom fiwohello difhmars riwosfearth fnnvklike fiiwjENDSTARTdifh, i'm fiwo riwosf.i ...
- POJ 3262 Protecting the Flowers 【贪心】
题意:有n个牛在FJ的花园乱吃.所以FJ要赶他们回牛棚.每个牛在被赶走之前每秒吃Di个花朵.赶它回去FJ来回要花的总时间是Ti×2.在被赶走的过程中,被赶走的牛就不能乱吃 思路: 先赶走破坏力大的牛假 ...
- java:冒泡排序、选择排序、插入排序实现
整数排序 给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法. 样例 样例 1: 输入: [3, 2, 1, 4, 5] 输出: [1, 2, 3, 4, 5] ...
- HDU1711 Number Sequence KMP
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU1711 题意概括 给T组数据,每组有长度为n和m的母串和模式串.判断模式串是否是母串的子串,如果是输出 ...
- BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1195 题意概括 给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的. 题解 先造一个AC ...
- Unity 之 Game视图不显示
如果你确认的Scene视图没有问题,试着检查一下 物体的Layer 与 camera的Culling mask是否一致,或者说camera的Culling mask中是否包含物体的layer 这是相机 ...
- Python3 图片水平镜像实现
# -*- coding: utf-8 -*- """ Created on Sun Feb 4 12:15:38 2018 @author: markli " ...