最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中JavaBean對(duì)象和Map的互相轉(zhuǎn)換方法實(shí)例

 更新時(shí)間:2022年11月11日 09:39:45   作者:畢竟尹穩(wěn)健  
為什么需要將javaBean和map進(jìn)行轉(zhuǎn)換,在很多應(yīng)用場(chǎng)景中,需要將key=value形式的數(shù)據(jù)與javaBean對(duì)象相互轉(zhuǎn)換,下面這篇文章主要給大家介紹了關(guān)于Java中JavaBean對(duì)象和Map的互相轉(zhuǎn)換的相關(guān)資料,需要的朋友可以參考下

1.JavaBean轉(zhuǎn)Map

1.1.簡(jiǎn)介

這篇博客是通過(guò)反射來(lái)進(jìn)行實(shí)現(xiàn)轉(zhuǎn)換的

在學(xué)習(xí)redis中,發(fā)現(xiàn)了一個(gè)知識(shí)點(diǎn),就是Java對(duì)象轉(zhuǎn)map,視頻中的內(nèi)容是通過(guò)hutool工具轉(zhuǎn)換的,但是我們學(xué)習(xí)者肯定不能只通過(guò)工具來(lái)進(jìn)行轉(zhuǎn)換,更多的是通過(guò)這個(gè)知識(shí)點(diǎn)學(xué)習(xí)到他的底層是如何進(jìn)行轉(zhuǎn)換的。

1.2.反射知識(shí)

// 新建一個(gè)對(duì)象
UserDTO userDTO = new UserDTO(1L,"zhangsan","123");
// 通過(guò)reflect獲取所有屬性
// userDTO.getClass().getDeclaredFields() // 暴力獲取所有的屬性字段
for (Field field : userDTO.getClass().getDeclaredFields()) {
    // 設(shè)置暴力反射,獲取私有屬性
    field.setAccessible(true);
    try {
    	/**
    	field.getName() 獲取屬性字段的字段名稱
    	field.get(userDTO)  相當(dāng)于  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.簡(jiǎn)單轉(zhuǎn)換

@Test
    void contextLoads() {
        Map<String, Object> map = new HashMap<>();
        UserDTO userDTO = new UserDTO(1L,"zhangsan","123");
        // 通過(guò)reflect獲取所有屬性
        for (Field field : userDTO.getClass().getDeclaredFields()) {
            // 設(shè)置暴力反射,獲取私有屬性
            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.屬性里面套屬性轉(zhuǎn)換

實(shí)體類(lèi)

package com.sky;

import com.sky.dto.UserDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * @author 尹穩(wěn)健~
 * @version 1.0
 * @time 2022/11/9
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Clazz {
    private String ClazzName;
    @OneSelf
    List<UserDTO> userDTOList;
}

自定義注解

package com.sky;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * @author 尹穩(wěn)健~
 * @version 1.0
 * @time 2022/11/9
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface OneSelf {
}

轉(zhuǎn)換方法:

public Map<String,Object> beanToMap(Object o){
        Map<String, Object> map = new HashMap<>();
        // 通過(guò)reflect獲取所有樹(shù)形
        for (Field field : o.getClass().getDeclaredFields()) {
            // 設(shè)置暴力反射,獲取私有屬性
            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<String, Object> 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.總結(jié)

  • 就是通過(guò)自定義注解來(lái)判斷是否需要遞歸轉(zhuǎn)換
  • 嵌套的話,應(yīng)該還有其他方法可以研究一下

2.Map轉(zhuǎn)JavaBean對(duì)象

2.1.簡(jiǎn)介

在實(shí)際項(xiàng)目中相信大多數(shù)人都使用過(guò)工具類(lèi),比如說(shuō)commons下的和hutool工具類(lèi),但是我們只是知道如何調(diào)用這個(gè)API,而不知道他方法的底層是通過(guò)什么樣的思路進(jìn)行實(shí)現(xiàn)的。
通過(guò)對(duì)一些底層的了解和學(xué)習(xí),能學(xué)到更多的知識(shí),了解底層的一些實(shí)現(xiàn)方式,拓展自己的思維。
我將從下面開(kāi)始介紹如何將JavaBean對(duì)象轉(zhuǎn)換為Map。

2.2.Introspector介紹

Introspector是JDK中java.beans包下的類(lèi),它為目標(biāo)JavaBean提供了一種了解原類(lèi)方法、屬性和事件的標(biāo)準(zhǔn)方法。通俗的說(shuō),就是可以通過(guò)Introspector構(gòu)建一個(gè)BeanInfo對(duì)象,而這個(gè)BeanInfo對(duì)象中包含了目標(biāo)類(lèi)中的屬性、方法和事件的描述信息,然后可以使用這個(gè)BeanInfo對(duì)象對(duì)目標(biāo)對(duì)象進(jìn)行相關(guān)操作。

JDK原文:

  • Introspector類(lèi)提供了一種標(biāo)準(zhǔn)的工具來(lái)了解目標(biāo)Java Bean支持的屬性,事件和方法。
  • 對(duì)于這三種信息中的每一種,Introspector將分別分析bean的類(lèi)和超類(lèi),尋找顯式或隱式信息,并使用該信息構(gòu)建一個(gè)全面描述目標(biāo)bean的BeanInfo對(duì)象。
  • 對(duì)于每個(gè)類(lèi)“Foo”,如果存在相應(yīng)的“FooBeanInfo”類(lèi),在查詢信息時(shí)提供非空值,則顯式信息可能可用。 我們首先通過(guò)獲取目標(biāo)bean類(lèi)的完整的包限定名稱并附加“BeanInfo”來(lái)形成一個(gè)新的類(lèi)名稱來(lái)查找BeanInfo類(lèi)。 如果失敗,那么我們將使用該名稱的最終類(lèi)名組件,并在BeanInfo包搜索路徑中指定的每個(gè)包中查找該類(lèi)。

方法介紹:

修飾符返回類(lèi)型方法名稱和參數(shù)描述
staticStringdecapitalize(String name)實(shí)用方法來(lái)取一個(gè)字符串并將其轉(zhuǎn)換為正常的Java變量名稱大小寫(xiě)。
staticvoidflushCaches()沖洗所有Introspector的內(nèi)部緩存。
staticvoidflushFromCaches(類(lèi)<?> clz)刷新內(nèi)部緩存信息給一個(gè)給定的類(lèi)。
staticBeanInfogetBeanInfo(類(lèi)<?> beanClass)內(nèi)省Java Bean并了解其所有屬性,暴露的方法和事件。
staticBeanInfogetBeanInfo(類(lèi)<?> beanClass, 類(lèi)<?> stopClass)內(nèi)省Java bean并了解其屬性,暴露的方法,低于給定的“停止”點(diǎn)。
staticBeanInfogetBeanInfo(類(lèi)<?> beanClass, 類(lèi)<?> stopClass, int flags)對(duì)Java Bean進(jìn)行內(nèi)省,并了解其所有屬性,暴露的方法和事件,低于給定的 stopClass點(diǎn),受到一些控制 flags 。
staticBeanInfogetBeanInfo(類(lèi)<?> beanClass, int flags)對(duì)Java bean進(jìn)行內(nèi)省,并了解其所有屬性,公開(kāi)方法和事件,并遵守一些控制標(biāo)志。
staticString[]getBeanInfoSearchPath()獲取將用于查找BeanInfo類(lèi)的包名稱列表。
staticvoidsetBeanInfoSearchPath(String[] path)更改將用于查找BeanInfo類(lèi)的包名稱列表。

2.3.BeanInfo介紹

JDK原文:

  • 使用BeanInfo界面創(chuàng)建一個(gè)BeanInfo類(lèi),并提供關(guān)于bean的方法,屬性,事件和其他功能的顯式信息。
  • 在開(kāi)發(fā)您的bean時(shí),您可以實(shí)現(xiàn)應(yīng)用任務(wù)所需的bean功能,省略其余的BeanInfo功能。
  • 它們將通過(guò)自動(dòng)分析獲得,通過(guò)使用低級(jí)反射的bean方法和應(yīng)用標(biāo)準(zhǔn)設(shè)計(jì)模式。 您有機(jī)會(huì)通過(guò)各種描述符類(lèi)提供其他bean信息。

關(guān)鍵方法介紹:

修飾符返回類(lèi)型方法名稱和參數(shù)描述
無(wú)PropertyDescriptor[]getPropertyDescriptors()返回bean的所有屬性的描述符。

2.4用反射實(shí)現(xiàn)轉(zhuǎn)換

實(shí)體類(lèi):

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;
}

方法封裝:

反射知識(shí)介紹:

// 利用反射調(diào)用構(gòu)造器實(shí)例化對(duì)象
Object object = beanClass.getDeclaredConstructor().newInstance();
// 通過(guò)實(shí)例化對(duì)象的class對(duì)象,獲取所有的字段
Field[] fields = object.getClass().getDeclaredFields();
// 返回屬性字段的修飾符
int mod = field.getModifiers();

關(guān)鍵方法:

public Object mapToBean(Map<String,Object> map,Class<?> beanClass) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 利用反射調(diào)用構(gòu)造器實(shí)例化對(duì)象
        Object object = beanClass.getDeclaredConstructor().newInstance();
        // 通過(guò)實(shí)例化對(duì)象的class對(duì)象,獲取所有的字段
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            // 返回屬性字段的修飾符
            int mod = field.getModifiers();
            // 如果是靜態(tài)或者final修飾的不需要添加
            if (Modifier.isStatic(mod)|| Modifier.isFinal(mod)){
                continue;
            }
            // 暴力獲取私有屬性
            field.setAccessible(true);
            // 相當(dāng)于object.setterField()
            field.set(object,map.get(field.getName()));
        }
        return object;
    }

2.5.利用Introspector(內(nèi)省)的方式轉(zhuǎn)換

public Object mapToBean2(Map<String,Object> map,Class<?> beanClass) throws Exception{
        // 利用class對(duì)象調(diào)用構(gòu)造器實(shí)例化對(duì)象
        Object object = beanClass.getDeclaredConstructor().newInstance();
        // 內(nèi)省Java bean并了解其屬性,暴露的方法,==簡(jiǎn)單來(lái)說(shuō)就是將屬性封裝到了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;
    }

總結(jié)

到此這篇關(guān)于Java中JavaBean對(duì)象和Map的互相轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Java JavaBean和Map互相轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring異常捕獲且回滾事務(wù)解決方案

    Spring異常捕獲且回滾事務(wù)解決方案

    這篇文章主要介紹了Spring異常捕獲且回滾事務(wù)解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Java 使用Calendar計(jì)算時(shí)間的示例代碼

    Java 使用Calendar計(jì)算時(shí)間的示例代碼

    這篇文章主要介紹了Java 使用Calendar計(jì)算時(shí)間的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 優(yōu)雅地在Java 8中處理異常的方法詳解

    優(yōu)雅地在Java 8中處理異常的方法詳解

    異常處理是我們?cè)谌粘i_(kāi)發(fā)中經(jīng)常會(huì)遇到的一種需求,下面這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅地在Java 8中處理異常的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們來(lái)一起看看吧
    2019-01-01
  • 簡(jiǎn)單講解Java的Future編程模式

    簡(jiǎn)單講解Java的Future編程模式

    這篇文章主要介紹了Java的Future編程模式,包括對(duì)異步和并發(fā)的一些設(shè)計(jì)思維,需要的朋友可以參考下
    2015-11-11
  • java實(shí)現(xiàn)收藏功能

    java實(shí)現(xiàn)收藏功能

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)收藏功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Java如何基于okhttp請(qǐng)求SSE接口流式返回詳解

    Java如何基于okhttp請(qǐng)求SSE接口流式返回詳解

    對(duì)于流式返回,Spring Boot提供了兩種不同的方式,下面這篇文章主要給大家介紹了關(guān)于Java如何基于okhttp請(qǐng)求SSE接口流式返回的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • Idea中Java項(xiàng)目如何修改項(xiàng)目名

    Idea中Java項(xiàng)目如何修改項(xiàng)目名

    這篇文章主要介紹了Idea中Java項(xiàng)目如何修改項(xiàng)目名問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • java基礎(chǔ)學(xué)習(xí)筆記之類(lèi)加載器

    java基礎(chǔ)學(xué)習(xí)筆記之類(lèi)加載器

    java中的類(lèi)加載器:java虛擬機(jī)中可以安裝多個(gè)類(lèi)加載器,系統(tǒng)默認(rèn)三個(gè)主要類(lèi)加載器,每個(gè)類(lèi)負(fù)責(zé)加載特定位置的類(lèi):BootStrap, ExtClassLoader,AppClassLoader類(lèi)加載器也是一個(gè)java類(lèi),因此類(lèi)加載器也需要被加載,所以必須有第一個(gè)類(lèi)加載器不是java類(lèi)
    2016-02-02
  • 關(guān)于快速測(cè)試API接口的一個(gè)新技能

    關(guān)于快速測(cè)試API接口的一個(gè)新技能

    這篇文章主要給大家介紹了關(guān)于快速測(cè)試API接口的一個(gè)新技能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • 關(guān)于SpringBoot在有Ajax時(shí)候不跳轉(zhuǎn)的問(wèn)題解決

    關(guān)于SpringBoot在有Ajax時(shí)候不跳轉(zhuǎn)的問(wèn)題解決

    最近在使用Ajax來(lái)發(fā)送一些數(shù)據(jù)給后臺(tái)一個(gè)Controller,但是遇到些問(wèn)題,所以下面這篇文章主要給大家介紹了關(guān)于SpringBoot在有Ajax時(shí)候不跳轉(zhuǎn)問(wèn)題的解決辦法,需要的朋友可以參考下
    2022-05-05

最新評(píng)論

辉南县| 花莲市| 会泽县| 锦州市| 顺义区| 西青区| 固阳县| 乌审旗| 湟中县| 城固县| 垫江县| 天等县| 萨迦县| 青铜峡市| 晋中市| 喀什市| 弥勒县| 蓬安县| 六盘水市| 丹棱县| 六安市| 曲阳县| 兴国县| 即墨市| 建湖县| 东乡族自治县| 滕州市| 读书| 富民县| 岳西县| 永定县| 锦州市| 宁陵县| 永胜县| 通道| 浦东新区| 汉阴县| 龙海市| 乌兰浩特市| 白沙| 鹤岗市|