Java中JavaBean对象和Map的互相转换
admin
2024-01-20 14:20:40
0次

Java中JavaBean对象和Map的互相转换

  • 1.JavaBean转Map
    • 1.1.简介
    • 1.2.反射知识
    • 1.3.简单转换
    • 1. 4.属性里面套属性转换
    • 1. 5.总结
  • 2.Map转JavaBean对象
    • 2.1.简介
    • 2.2.Introspector介绍
    • 2.3.BeanInfo介绍
    • 2.4用反射实现转换
    • 2.5.利用Introspector(内省)的方式转换

1.JavaBean转Map

1.1.简介

这篇博客是通过反射进行实现转换的

在学习redis中,发现了一个知识点,就是Java对象转map,视频中的内容是通过hutool工具转换的,但是我们学习者肯定不能只通过工具来进行转换,更多的是通过这个知识点学习到他的底层是如何进行转换的。

1.2.反射知识

// 新建一个对象
UserDTO userDTO = new UserDTO(1L,"zhangsan","123");
// 通过reflect获取所有属性
// userDTO.getClass().getDeclaredFields() // 暴力获取所有的属性字段
for (Field field : userDTO.getClass().getDeclaredFields()) {// 设置暴力反射,获取私有属性field.setAccessible(true);try {/**field.getName() 获取属性字段的字段名称field.get(userDTO)  相当于  userDTO.getField();  */map.put(field.getName(),field.get(userDTO));} catch (IllegalAccessException e) {e.printStackTrace();}
}
for (String s : map.keySet()) {System.out.println(s+"=="+map.get(s));
}

1.3.简单转换

@Testvoid contextLoads() {Map map = new HashMap<>();UserDTO userDTO = new UserDTO(1L,"zhangsan","123");// 通过reflect获取所有属性for (Field field : userDTO.getClass().getDeclaredFields()) {// 设置暴力反射,获取私有属性field.setAccessible(true);try {map.put(field.getName(),field.get(userDTO));} catch (IllegalAccessException e) {e.printStackTrace();}}for (String s : map.keySet()) {System.out.println(s+"=="+map.get(s));}}

1. 4.属性里面套属性转换

实体类

package com.sky;import com.sky.dto.UserDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.List;/*** @author 尹稳健~* @version 1.0* @time 2022/11/9*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Clazz {private String ClazzName;@OneSelfList userDTOList;
}

自定义注解

package com.sky;import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;/*** @author 尹稳健~* @version 1.0* @time 2022/11/9*/
@Retention(RetentionPolicy.RUNTIME)
public @interface OneSelf {
}

转换方法:

public Map beanToMap(Object o){Map map = new HashMap<>();// 通过reflect获取所有树形for (Field field : o.getClass().getDeclaredFields()) {// 设置暴力反射,获取私有属性field.setAccessible(true);try {if (field.get(o) != null){Class aClass = field.get(o).getClass();OneSelf annotation = aClass.getAnnotation(OneSelf.class);if (annotation!=null){Map beanToMap = beanToMap(field.get(o));map.put(field.getName(),beanToMap);}else{map.put(field.getName(),field.get(o));}}} catch (IllegalAccessException e) {e.printStackTrace();}}return map;}

1. 5.总结

  • 就是通过自定义注解来判断是否需要递归转换
  • 嵌套的话,应该还有其他方法可以研究一下

2.Map转JavaBean对象

2.1.简介

在实际项目中相信大多数人都使用过工具类,比如说commons下的和hutool工具类,但是我们只是知道如何调用这个API,而不知道他方法的底层是通过什么样的思路进行实现的。
通过对一些底层的了解和学习,能学到更多的知识,了解底层的一些实现方式,拓展自己的思维。
我将从下面开始介绍如何将JavaBean对象转换为Map。

2.2.Introspector介绍

Introspector是JDK中java.beans包下的类,它为目标JavaBean提供了一种了解原类方法、属性和事件的标准方法。通俗的说,就是可以通过Introspector构建一个BeanInfo对象,而这个BeanInfo对象中包含了目标类中的属性、方法和事件的描述信息,然后可以使用这个BeanInfo对象对目标对象进行相关操作。

JDK原文:

  • Introspector类提供了一种标准的工具来了解目标Java Bean支持的属性,事件和方法。
  • 对于这三种信息中的每一种,Introspector将分别分析bean的类和超类,寻找显式或隐式信息,并使用该信息构建一个全面描述目标bean的BeanInfo对象。
  • 对于每个类“Foo”,如果存在相应的“FooBeanInfo”类,在查询信息时提供非空值,则显式信息可能可用。 我们首先通过获取目标bean类的完整的包限定名称并附加“BeanInfo”来形成一个新的类名称来查找BeanInfo类。 如果失败,那么我们将使用该名称的最终类名组件,并在BeanInfo包搜索路径中指定的每个包中查找该类。

方法介绍:

修饰符返回类型方法名称和参数描述
staticStringdecapitalize(String name)实用方法来取一个字符串并将其转换为正常的Java变量名称大小写。
staticvoidflushCaches()冲洗所有Introspector的内部缓存。
staticvoidflushFromCaches(类 clz)刷新内部缓存信息给一个给定的类。
staticBeanInfogetBeanInfo(类 beanClass)内省Java Bean并了解其所有属性,暴露的方法和事件。
staticBeanInfogetBeanInfo(类 beanClass, 类 stopClass)内省Java bean并了解其属性,暴露的方法,低于给定的“停止”点。
staticBeanInfogetBeanInfo(类 beanClass, 类 stopClass, int flags)对Java Bean进行内省,并了解其所有属性,暴露的方法和事件,低于给定的 stopClass点,受到一些控制 flags 。
staticBeanInfogetBeanInfo(类 beanClass, int flags)对Java bean进行内省,并了解其所有属性,公开方法和事件,并遵守一些控制标志。
staticString[]getBeanInfoSearchPath()获取将用于查找BeanInfo类的包名称列表。
staticvoidsetBeanInfoSearchPath(String[] path)更改将用于查找BeanInfo类的包名称列表。

2.3.BeanInfo介绍

JDK原文:

  • 使用BeanInfo界面创建一个BeanInfo类,并提供关于bean的方法,属性,事件和其他功能的显式信息。
  • 在开发您的bean时,您可以实现应用任务所需的bean功能,省略其余的BeanInfo功能。
  • 它们将通过自动分析获得,通过使用低级反射的bean方法和应用标准设计模式。 您有机会通过各种描述符类提供其他bean信息。

关键方法介绍:

修饰符返回类型方法名称和参数描述
无PropertyDescriptor[]getPropertyDescriptors()返回bean的所有属性的描述符。

2.4用反射实现转换

实体类:

package com.sky.dto;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {private Long id;private String nickName;private String icon;
}

方法封装:
反射知识介绍:

// 利用反射调用构造器实例化对象
Object object = beanClass.getDeclaredConstructor().newInstance();
// 通过实例化对象的class对象,获取所有的字段
Field[] fields = object.getClass().getDeclaredFields();
// 返回属性字段的修饰符
int mod = field.getModifiers();

关键方法:

public Object mapToBean(Map map,Class beanClass) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {// 利用反射调用构造器实例化对象Object object = beanClass.getDeclaredConstructor().newInstance();// 通过实例化对象的class对象,获取所有的字段Field[] fields = object.getClass().getDeclaredFields();for (Field field : fields) {// 返回属性字段的修饰符int mod = field.getModifiers();// 如果是静态或者final修饰的不需要添加if (Modifier.isStatic(mod)|| Modifier.isFinal(mod)){continue;}// 暴力获取私有属性field.setAccessible(true);// 相当于object.setterField()field.set(object,map.get(field.getName()));}return object;}

2.5.利用Introspector(内省)的方式转换

public Object mapToBean2(Map map,Class beanClass) throws Exception{// 利用class对象调用构造器实例化对象Object object = beanClass.getDeclaredConstructor().newInstance();// 内省Java bean并了解其属性,暴露的方法,==简单来说就是将属性封装到了BeanInfo里面==BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());// 返回bean的所有属性的描述符。PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {/*** java.beans.PropertyDescriptor[* name=icon; values={expert=false; visualUpdate=false; hidden=false;* enumerationValues=[Ljava.lang.Object;@75c77add; required=false};* propertyType=class java.lang.String; readMethod=public java.lang.String com.sky.dto.UserDTO.getIcon();* writeMethod=public void com.sky.dto.UserDTO.setIcon(java.lang.String)]*/System.out.println(propertyDescriptor);// 获取属性的setter方法Method setter = propertyDescriptor.getWriteMethod();if (setter!=null){// 获取值Object o = map.get(propertyDescriptor.getName());if (o!=null){// 利用反射将属性赋值setter.invoke(object,o);}}}return object;}

相关内容

热门资讯

小赢淘金APP期货投资骗局,平...   “小赢淘金”之流,最擅长的就是用“注册送现金”、“充值返券”的糖衣炮弹来引流。别天真地以为那是福...
八方淘金APP非法期货交易欺骗...   警惕!八方生财、每日淘金、小赢淘金、悟空订购、蜻蜓订购、斗金订购等APP均涉嫌非法期货交易!  ...
智易购APP贵金属订购交易骗局...   很多人看到“3元起投”“充值送福利”“操作简单”“随时提现”这类宣传,很容易把智易购APP当成普...
喜玛银庄APP商品订购投资骗局...   喜玛银庄APP白银、铂金“现货订购”骗局警示:无资质平台涉嫌非法期货交易,投资者爆仓后如何维权?...
吉鑫乐享APP炒贵金属订购交易...   近期,多名投资者反映在“吉鑫乐享APP”进行贵金属投资时遭遇严重亏损,甚至血本无归。看似正规的“...
易掘金APP虚假期货投资骗局,...   “易掘金”的APP它打着“高收益、灵活投资”的旗号,宣称通过“商品订购”就能轻松赚钱,吸引了不少...
在大吉订购APP订购交易亏损被...   近期,不少投资者反映在“大吉订购App”上投资白银、铂金等商品遭遇严重亏损。该平台宣称提供现货订...
铂银壹号APP商品订购交易亏损...   许多中小投资者误以为网上的“商品现货订购”是合规合法的理财渠道,殊不知这背后隐藏着巨大的合规风险...
兴鑫淘金APP贵金属订购交易亏...   白银、贵金属或其他商品类投资,除国家批准的正规期货交易场所及持牌期货公司外,市面上大量第三方交易...
铂银掘金APP无资质的违规平台...   铂银掘金等平台的投资者,往往是被“注册送现金”“充值返现券”“首单免亏”等广告话术吸引,进而下载...
八方淘金APP订购交易不合规,...   “八方淘金APP”“铂银掘金APP”“铂银壹号APP”等软件被指以“现货订购”为名,实际采用高杠...
在指尖订购APP订购商品亏损被...   指尖订购APP这类平台,表面是“订购交易”,实则是披着电商外衣的非法期货陷阱。绝大多数投资者被蒙...
在犀贝易购APP做商品订购交易...   市面上打着“现货投资”“贵金属交易”旗号的APP并不少,但真正合规、受监管的平台并不多。犀贝易购...
易达淘金APP虚假商品订购交易...   易达淘金APP存在严重的虚假宣传与违规交易行为。该平台打着“商品订购”的旗号,实则通过不合规的交...
大浪淘金APP白银订购亏损被骗...   大浪淘金APP最隐蔽的套路,在于其完全封闭的内盘交易系统。表面上,它宣称与国际贵金属市场接轨;实...
一品好购APP上订购白银出现亏...   一品好购APP原名“一品订购”,运营方为上海宝智未来信息技术有限公司。近期不少投资者反映在该平台...
九州订购APP贵金属订购投资骗...   九州订购APP正通过抖.音、快手、今日头条等平台大量投放投资广告,用“5元起投”“充值返现”“0...
坚锅淘金APP交易软件并不正规...   当前,市面上大量所谓的“现货商城订购”交易软件,早已偏离了正常的实物商品买卖,演变为高杠杆、高手...
斗金订购APP贵金属期货交易骗...   斗金订购APP的投资者往往被铺天盖地的广告宣传所诱导——注册即送现金、充值返现券等看似诱人的福利...
警惕!云启购APP违规经营,披...   "5元起投、充值返现、稳赚不赔"——这些诱人的广告语背后,可能是一个精心设计的金融陷阱。  近期...