亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Hutool開(kāi)發(fā)利器MapProxy類(lèi)使用技巧詳解

 更新時(shí)間:2022年10月07日 09:09:13   作者:JAVA旭陽(yáng)  
這篇文章主要為大家介紹了Hutool開(kāi)發(fā)利器MapProxy類(lèi)使用技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

概述

Hutool是一個(gè)小而全的Java工具類(lèi)庫(kù),通過(guò)靜態(tài)方法封裝,降低相關(guān)API的學(xué)習(xí)成本,提高工作效率,使Java擁有函數(shù)式語(yǔ)言般的優(yōu)雅,讓Java語(yǔ)言也可以“甜甜的”。

目前公司項(xiàng)目中主要采用Hutool作為項(xiàng)目的工具包,相對(duì)于google的guava, hutool的工具類(lèi)采用中文注釋?zhuān)臃蠂?guó)人使用。所謂知己知彼,我們需要了解Hutool都具有什么樣的功能,才能夠最大化發(fā)揮它的價(jià)值。

本文主要就hutool 5.8.8版本中MapProxy的使用。

場(chǎng)景引入

其實(shí)Map在get的時(shí)候是比較危險(xiǎn)的,你可能不知道它是什么類(lèi)型,需要進(jìn)行強(qiáng)制,舉個(gè)例子如下:

@Test
public void testMapProxy1() {
    Map<String, Object> userMap = MapUtil.newHashMap(16);
    userMap.put("username", "alvin");
    userMap.put("age", 20);
    // 使用map的時(shí)候, 需要進(jìn)行強(qiáng)轉(zhuǎn),一旦類(lèi)型錯(cuò)誤,會(huì)報(bào)錯(cuò)
    String age = (String)userMap.get("age");
}

運(yùn)行結(jié)果:

那有什么更好的解決方案嗎?Hutool提供了一種解決方案給我們。

MapProxy使用

依賴引入

<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.8.8</version>
</dependency>

定義一個(gè)可訪問(wèn)接口

interface MapUser {
    String getUsername();
    Integer getAge();
    MapUser setAge(Integer age);
}

通過(guò)MapProxy訪問(wèn)

@Test
public void testMapProxy2() {
    Map<String, Object> userMap = MapUtil.newHashMap(16);
    userMap.put("username", "alvin");
    userMap.put("age", 20);
    MapProxy mapProxy = MapProxy.create(userMap);
    Integer age = mapProxy.getInt("age", 18);
    Assert.assertTrue(age == 20);
    // 通過(guò)代理的方式
    MapUser mapUser = mapProxy.toProxyBean(MapUser.class);
    // 后續(xù)訪問(wèn)會(huì)變的更加安全
    Assert.assertTrue(mapUser.getAge() == 20);
    mapUser.setAge(30);
    Assert.assertTrue(mapUser.getAge() == 30);
}

MapProxy源碼解析

Map代理,提供各種getXXX方法,并提供默認(rèn)值支持,它的類(lèi)結(jié)構(gòu)圖如下:

  • 實(shí)現(xiàn)了OptNullBasicTypeFromObjectGetter接口, 提供了基本類(lèi)型的get, 在不提供默認(rèn)值的情況下, 如果值不存在或獲取錯(cuò)誤,返回null, 比如:mapProxy.getInt("age", 18)。
  • 實(shí)現(xiàn)了InvocationHandler接口,支持jdk的動(dòng)態(tài)代理,生成代理對(duì)象。
public <T> T toProxyBean(Class<T> interfaceClass) {
    return (T) Proxy.newProxyInstance(ClassLoaderUtil.getClassLoader(), new Class<?>[]{interfaceClass}, this);
}
  • toProxyBean方法就是生成代理對(duì)象,最終會(huì)調(diào)用代理類(lèi)的invoke方法,這里的代理類(lèi)就是MapProxy本身。
public Object invoke(Object proxy, Method method, Object[] args) {
    final Class<?>[] parameterTypes = method.getParameterTypes();
    // 如果調(diào)用方法參數(shù)為空
    if (ArrayUtil.isEmpty(parameterTypes)) {
        final Class<?> returnType = method.getReturnType();
        // 方法返回值不是void
        if (void.class != returnType) {
            // 匹配Getter
            final String methodName = method.getName();
            String fieldName = null;
            if (methodName.startsWith("get")) {
                // 匹配getXXX
                fieldName = StrUtil.removePreAndLowerFirst(methodName, 3);
            } else if (BooleanUtil.isBoolean(returnType) && methodName.startsWith("is")) {
                // 匹配isXXX
                fieldName = StrUtil.removePreAndLowerFirst(methodName, 2);
            }else if ("hashCode".equals(methodName)) {
                return this.hashCode();
            } else if ("toString".equals(methodName)) {
                return this.toString();
            }
            if (StrUtil.isNotBlank(fieldName)) {
                if (false == this.containsKey(fieldName)) {
                    // 駝峰不存在轉(zhuǎn)下劃線嘗試
                    fieldName = StrUtil.toUnderlineCase(fieldName);
                }
                return Convert.convert(method.getGenericReturnType(), this.get(fieldName));
            }
        }
        // 如果方法參數(shù)不為空
    } else if (1 == parameterTypes.length) {
        // 匹配Setter
        final String methodName = method.getName();
        if (methodName.startsWith("set")) {
            final String fieldName = StrUtil.removePreAndLowerFirst(methodName, 3);
            if (StrUtil.isNotBlank(fieldName)) {
                this.put(fieldName, args[0]);
                final Class<?> returnType = method.getReturnType();
                // 判斷返回類(lèi)型是不是代理類(lèi)的實(shí)例
                if(returnType.isInstance(proxy)){
                    return proxy;
                }
            }
        } else if ("equals".equals(methodName)) {
            return this.equals(args[0]);
        }
    }
    throw new UnsupportedOperationException(method.toGenericString());
}

總結(jié)

本文主要講解了Hutool中的MapProxy類(lèi)的使用,希望對(duì)大家有幫助

以上就是Hutool開(kāi)發(fā)利器MapProxy類(lèi)使用技巧詳解的詳細(xì)內(nèi)容,更多關(guān)于Hutool開(kāi)發(fā)MapProxy類(lèi)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java 三元操作符用法說(shuō)明

    java 三元操作符用法說(shuō)明

    這篇文章主要介紹了java 三元操作符用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • 使用Idea快速搭建SpringMVC項(xiàng)目的詳細(xì)步驟記錄

    使用Idea快速搭建SpringMVC項(xiàng)目的詳細(xì)步驟記錄

    這篇文章主要給大家介紹了關(guān)于使用Idea快速搭建SpringMVC項(xiàng)目的詳細(xì)步驟,Spring?MVC是一種基于MVC模式的框架,它是Spring框架的一部分,它提供了一種更簡(jiǎn)單和更有效的方式來(lái)構(gòu)建Web應(yīng)用程序,需要的朋友可以參考下
    2024-05-05
  • SpringMVC使用ResponseEntity實(shí)現(xiàn)文件上傳下載

    SpringMVC使用ResponseEntity實(shí)現(xiàn)文件上傳下載

    這篇文章主要為大家介紹了SpringMVC使用ResponseEntity實(shí)現(xiàn)文件上傳下載,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Windows下使用Graalvm將Springboot應(yīng)用編譯成exe大大提高啟動(dòng)和運(yùn)行效率(推薦)

    Windows下使用Graalvm將Springboot應(yīng)用編譯成exe大大提高啟動(dòng)和運(yùn)行效率(推薦)

    這篇文章主要介紹了Windows下使用Graalvm將Springboot應(yīng)用編譯成exe大大提高啟動(dòng)和運(yùn)行效率,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • SpringBoot模板引擎之Thymeleaf的使用

    SpringBoot模板引擎之Thymeleaf的使用

    這篇文章主要介紹了SpringBoot模板引擎之Thymeleaf的使用,模板引擎是以業(yè)務(wù)邏輯層和表現(xiàn)層分離為目的的,將規(guī)定格式的模板代碼轉(zhuǎn)換為業(yè)務(wù)數(shù)據(jù)的算法實(shí)現(xiàn),它可以是一個(gè)過(guò)程代碼、一個(gè)類(lèi),甚至是一個(gè)類(lèi)庫(kù),需要的朋友可以參考下
    2023-10-10
  • java HashMap,TreeMap與LinkedHashMap的詳解

    java HashMap,TreeMap與LinkedHashMap的詳解

    這篇文章主要介紹了 java HashMap,TreeMap與LinkedHashMap的詳解的相關(guān)資料,這里提供實(shí)例代碼,幫助大家學(xué)習(xí)理解 這部分的內(nèi)容,需要的朋友可以參考下
    2016-11-11
  • java之minio文件服務(wù)器的日常操作

    java之minio文件服務(wù)器的日常操作

    本文介紹如何在Java項(xiàng)目中配置Minio服務(wù),通過(guò)創(chuàng)建minioConfig和minioDto來(lái)管理連接信息,并通過(guò)minioUtils工具類(lèi)實(shí)現(xiàn)文件的上傳、下載和刪除功能,詳細(xì)說(shuō)明了如何從application.yml文件中讀取配置,并強(qiáng)調(diào)了避免static情況下minioDto為null的問(wèn)題,另外,提到刪除操作是延遲的
    2024-10-10
  • 基于Transactional事務(wù)的使用以及注意說(shuō)明

    基于Transactional事務(wù)的使用以及注意說(shuō)明

    這篇文章主要介紹了Transactional事務(wù)的使用以及注意說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring服務(wù)注解有哪些

    Spring服務(wù)注解有哪些

    這篇文章主要介紹了Spring服務(wù)注解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2016-11-11
  • Spring?Boot日志基礎(chǔ)使用之如何設(shè)置日志級(jí)別

    Spring?Boot日志基礎(chǔ)使用之如何設(shè)置日志級(jí)別

    這篇文章主要介紹了Spring?Boot日志基礎(chǔ)使用設(shè)置日志級(jí)別的方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09

最新評(píng)論