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

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使用

依賴(lài)引入

<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)文章

  • 詳解springmvc常用5種注解

    詳解springmvc常用5種注解

    在本篇里我們給大家總結(jié)了關(guān)于springmvc常用5種注解相關(guān)知識(shí)點(diǎn)以及實(shí)例代碼,需要的朋友們參考下。
    2019-07-07
  • 詳解如何在spring boot中使用spring security防止CSRF攻擊

    詳解如何在spring boot中使用spring security防止CSRF攻擊

    這篇文章主要介紹了詳解如何在spring boot中使用spring security防止CSRF攻擊,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Java文本文件操作方法實(shí)例詳解

    Java文本文件操作方法實(shí)例詳解

    這篇文章主要介紹了Java文本文件操作方法,以實(shí)例形式較為詳細(xì)的分析了java操作文本文件的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • java中stack(棧)的使用代碼實(shí)例

    java中stack(棧)的使用代碼實(shí)例

    這篇文章主要介紹了java中stack(棧)的使用代碼實(shí)例,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • 淺談java8中map的新方法--replace

    淺談java8中map的新方法--replace

    下面小編就為大家?guī)?lái)一篇淺談java8中map的新方法--replace。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-10-10
  • java中ThreadLocal和ThreadLocalMap淺析

    java中ThreadLocal和ThreadLocalMap淺析

    這篇文章主要介紹了java中ThreadLocal和ThreadLocalMap淺析,ThreadLocal類(lèi)用來(lái)設(shè)置線程私有變量?本身不儲(chǔ)存值?主要提供自身引用?和?操作ThreadLocalMap?屬性值得方法,需要的朋友可以參考下
    2023-09-09
  • JDK21新特性Record?Patterns記錄模式詳解(最新推薦)

    JDK21新特性Record?Patterns記錄模式詳解(最新推薦)

    這篇文章主要介紹了JDK21新特性Record?Patterns記錄模式詳解,本JEP建立在Pattern?Matching?for?instanceof(JEP?394)的基礎(chǔ)上,該功能已在JDK?16中發(fā)布,它與Pattern?Matching?for?switch(JEP?441)共同演進(jìn),需要的朋友可以參考下
    2023-09-09
  • 關(guān)于Spring?Ioc和DI注解的問(wèn)題

    關(guān)于Spring?Ioc和DI注解的問(wèn)題

    這篇文章主要介紹了Spring?Ioc和DI注解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Java對(duì)象傳遞與返回的細(xì)節(jié)問(wèn)題詳析

    Java對(duì)象傳遞與返回的細(xì)節(jié)問(wèn)題詳析

    我們知道這是一個(gè)核心概念,在Java中總是按值傳遞而不是按引用傳遞,下面這篇文章主要給大家介紹了關(guān)于Java對(duì)象傳遞與返回的細(xì)節(jié)問(wèn)題的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • Java開(kāi)發(fā)中synchronized的定義及用法詳解

    Java開(kāi)發(fā)中synchronized的定義及用法詳解

    這篇文章主要介紹了Java開(kāi)發(fā)中synchronized的定義及用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論

藁城市| 新和县| 卫辉市| 临洮县| 高州市| 巴彦县| 遵义县| 建始县| 冕宁县| 黄龙县| 柯坪县| 柞水县| 中超| 普兰店市| 陇西县| 两当县| 工布江达县| 突泉县| 肇东市| 镶黄旗| 陕西省| 渝中区| 吉木乃县| 安新县| 涞水县| 沭阳县| 西宁市| 洛扎县| 浪卡子县| 舞阳县| 大宁县| 叶城县| 高唐县| 吉林省| 达州市| 商城县| 丹巴县| 陈巴尔虎旗| 建水县| 土默特左旗| 博客|