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 ...
随机推荐
- Extjs MVC模式开发,循序渐进(一)
本文讲述extjs mvc的Helloworld,tabPanel,event,页面布局layout等内容. 本页包含:MVC模式案例(一)~MVC模式案例(六),从搭建extjs mvc到点击按钮生 ...
- 《Java程序性能优化》之并发优化
第四章 并行程序优化 1.非阻塞同步避免了基于锁的同步的缺陷,无锁算法没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销.CAS算法:包含3个参数CAS(v,e,n).V表示要更新的变量,E表示 ...
- asp.net core 微信APP支付(扫码支付,H5支付,公众号支付,app支付)之4
微信app支付需要以下参数,类封装如下 public class WxPayModel { /// <summary> /// 应用ID /// </summary> publ ...
- DevExpress学习笔记之如何获取Repository Item的值
上一章我们看到了如何在TreeList的单元格中动态绑定不同的控件,此类控件被称为In_Place Control.所谓“In_Place”,我的理解为“内置”控件,既然有“内”就相对的会有“外”,其 ...
- 020 RDD的理解
一:源码介绍RDD 1.RDD介绍 五大特性,保证了Spark的扩展性,容错性等特性. A list of partitions ====> 一个许多分区的集合,分区中包含数据 A functi ...
- 关于 C++ STL
一.STL简介 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.它是由Alexander Stepanov.Meng Lee和David R ...
- C++语言实现-拓扑排序
1.拓扑排序的概念 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则 ...
- pandas学习(创建数据,基本操作)
pandas学习(一) Pandas基本数据结构 Series类型数据 Dataframe类型 基本操作 Pandas基本数据结构 两种常用数据结构: Series 一维数组,与Numpy中的一维ar ...
- C# 启动外部程序的几种常用方法汇总
. 启动外部程序,不等待其退出. . 启动外部程序,等待其退出. . 启动外部程序,无限等待其退出. . 启动外部程序,通过事件监视其退出. 实现代码如下: // using System.Diagn ...
- 浅谈CSS和JQuery实现鼠标悬浮图片放大效果
对于刚刚学习网页前台设计的同学一定对图片的处理非常苦恼,那么这里简单的讲解一下几个图片处理的实例. 以.net为平台,微软的Visual Studio 2013为开发工具,当然前台技术还是采用CSS3 ...