欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java通過反射注解賦值的方法詳解

 更新時(shí)間:2022年07月22日 09:35:16   作者:小碼code  
這篇文章主要為大家詳細(xì)介紹了Java語言如何通過反射實(shí)現(xiàn)注解賦值,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下

前段時(shí)間,領(lǐng)導(dǎo)分配一個(gè)統(tǒng)計(jì)銷售區(qū)域匯總的數(shù)據(jù),解決方案使用到了反射獲取注解,通過注解獲取屬性或者設(shè)置字段屬性。

問題描述

查詢公司列表,分別是公司id、區(qū)域id、區(qū)域名稱:

公司id區(qū)域id區(qū)域名稱
11華南
22華北
32華北
43華東
53華東

創(chuàng)建公司類Company

public class Company {

    public Company(Integer id,  Integer areaId, String areaName) {
        this.id = id;
        this.areaId = areaId;
        this.areaName = areaName;
    }

    /**
     * 公司id
     */
    private Integer id;

    /**
     * 區(qū)域id
     */
    private Integer areaId;

    /**
     * 區(qū)域名稱
     */
    private String areaName;
     
    // 省略get/set方法 

}

最終解決

要求匯總各個(gè)區(qū)域公司數(shù)量,得到如下匯總:

區(qū)域id區(qū)域名稱公司總數(shù)
1華南1
2華北2
3華東2

最終區(qū)域?qū)嶓wAreaStatistic:

public class AreaStatistic {

    @ColumnProperty("華東大區(qū)")
    private Integer eastChina = 0;

    @ColumnProperty("華東id")
    private Integer eastChinaId;

    @ColumnProperty("華南大區(qū)")
    private Integer southChina = 0;

    @ColumnProperty("華南id")
    private Integer southChinaId;

    @ColumnProperty("華北大區(qū)")
    private Integer northChina = 0;

    @ColumnProperty("華北id")
    private Integer northChinaId;

    @Override
    public String toString() {
        return "AreaStatistic{\n" +
                "華東Id=" + eastChinaId +
                ",華東=" + eastChina +
                ", \n華南Id=" + southChinaId +
                ", 華南=" + southChina +
                ", \n華北Id=" + northChinaId +
                ", 華北=" + northChina +
                '}';
    }
    // 省略get/set方法
}

if/else 普通解法

AreaStatistic areaStatistic = new AreaStatistic();
for (Company company:companyList) {
    String areaName = company.getAreaName();
    if ("華南".equals(areaName)) {
        areaStatistic.setSouthChina(areaStatistic.getSouthChina()+1);
        areaStatistic.setSouthChinaId(company.getAreaId());
    } else if ("華北".equals(areaName)) {
        areaStatistic.setNorthChina(areaStatistic.getNorthChina()+1);
        areaStatistic.setNorthChinaId(company.getAreaId());
    } else if ("華東".equals(areaName)) {
        areaStatistic.setEastChina(areaStatistic.getEastChina()+1);
        areaStatistic.setEastChinaId(company.getAreaId());
    }
}

輸出:

華東Id=3,華東=2, 
華南Id=1, 華南=1, 
華北Id=2, 華北=2

這種做法的缺點(diǎn):

  • 要寫大量的條件判斷語句,非常的繁瑣。
  • 增加和減少統(tǒng)計(jì)區(qū)域,都要修改代碼。

針對上面的缺點(diǎn),使用反射獲取注解,通過注解獲取屬性賦值。

通過反射注解賦值屬性

解題思路

1.遍歷公司列表,獲取到區(qū)域id和區(qū)域名稱。

2.創(chuàng)建自定義注解@ColumnProperty:

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnProperty {

    String value() default "";

}

3.通過反射獲取屬性,然后遍歷字段屬性獲取注解。

AreaStatistic字段屬性上添加注解:

@ColumnProperty("華東大區(qū)")
private Integer eastChina = 0;

@ColumnProperty("華東id")
private Integer eastChinaId;

@ColumnProperty("華南大區(qū)")
private Integer southChina = 0;

@ColumnProperty("華南id")
private Integer southChinaId;

@ColumnProperty("華北大區(qū)")
private Integer northChina = 0;

@ColumnProperty("華北id")
private Integer northChinaId;

4.通過反射獲取屬性,然后遍歷字段屬性獲取注解。

Class staticClass = areaStatistic.getClass();
Field[] fields = staticClass.getDeclaredFields();
for (Field field : fields) {
    ColumnProperty property = field.getAnnotation(ColumnProperty.class);
    String value = property.value();
}

5.匹配區(qū)域名稱和字段屬性,比如遍歷公司區(qū)域是華東,就遍歷到華東大區(qū)注解對應(yīng)的字段,并賦值或者獲取字段值。

if (value != null) {
    int indexOf = value.indexOf("大區(qū)");
    if (indexOf != -1 && value.length() == 4) {
        if (areaName.equals(value.substring(0,2))) {
            field.setAccessible(true);
            field.set(areaStatistic,(Integer) field.get(areaStatistic) + 1);  
        }
     }
}

6.區(qū)域id賦值也是相同的解題思路。

根據(jù)上面的思路,有如下代碼匯總:

// 遍歷公司
for (Company company:companyList) {
  setAreaProperty(areaStatistic2,company.getAreaName(),company.getAreaId());
}

private void setAreaProperty(AreaStatistic areaStatistic,String areaName,Integer areaId) throws IllegalAccessException {
    // 反射獲取注解 
    Class staticClass = areaStatistic.getClass();
    Field[] fields = staticClass.getDeclaredFields();
    for (Field field : fields) {
        ColumnProperty property = field.getAnnotation(ColumnProperty.class);
        String value = property.value();
        if (value != null) {
            int indexOf = value.indexOf("大區(qū)");
            if (indexOf != -1 && value.length() == 4) {
                // 匹配到注解屬性并賦值 
                if (areaName.equals(value.substring(0,2))) {
                    field.setAccessible(true);
                    field.set(areaStatistic,(Integer) field.get(areaStatistic) + 1);
                    for (Field idField : fields) {
                        ColumnProperty idProperty = idField.getAnnotation(ColumnProperty.class);
                        String idValue = idProperty.value();
                        if (idValue.equals(areaName+"id")) {
                            idField.setAccessible(true);
                            idField.set(areaStatistic,areaId);
                            break;
                        }
                    }
                    break;
                }
            }
        }
    }
}

輸出:

華東Id=3,華東=2, 
華南Id=1, 華南=1, 
華北Id=2, 華北=2

匯總某些字段的和

上面算出各個(gè)區(qū)域的匯總之后,還要算出全部區(qū)域的總和,這里還是使用到注解,把屬性字段包含大區(qū)都累加起來:

AreaStatistic statistic = new AreaStatistic();
statistic.setEastChina(2);
statistic.setNorthChina(3);
statistic.setSouthChina(1);
int sum = 0;
Class staticClass = statistic.getClass();
Field[] fields = staticClass.getDeclaredFields();
for (Field field : fields) {
    ColumnProperty property = field.getAnnotation(ColumnProperty.class);
    String value = property.value();
    if (value.indexOf("大區(qū)") != -1) {
        field.setAccessible(true);
        sum += field.get(statistic) == null ? 0 : (Integer) field.get(statistic);
    }
}
System.out.println(sum);

輸出結(jié)果:

6

總結(jié)

1.自定義注解,通過反射獲取注解

2.通過匹配注解值,獲取或者復(fù)制對應(yīng)的字段屬性。

賦值主要代碼為:

field.setAccessible(true);
field.set(Model,value);

源碼

package reflect;

import org.junit.Test;
import reflect.annotation.ColumnProperty;
import reflect.model.AreaStatistic;
import reflect.model.Company;

import javax.print.DocFlavor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: laizc
 * @Date: created in 2022-07-21
 * @desc: 通過注解設(shè)值
 */
public class SetValueByAnnotation {

    /**
     * 通過屬性賦值
     */
    @Test
    public void test() throws IllegalAccessException {
        // 添加數(shù)據(jù)
        Company company5 = new Company(1,1,"華南");
        Company company1 = new Company(2,2,"華北");
        Company company2 = new Company(3,2,"華北");
        Company company3 = new Company(4,3,"華東");
        Company company4 = new Company(5,3,"華東");
        List<Company> companyList = new ArrayList<>();
        companyList.add(company5);
        companyList.add(company1);
        companyList.add(company2);
        companyList.add(company3);
        companyList.add(company4);

        // 解法1
        AreaStatistic areaStatistic = new AreaStatistic();
        for (Company company:companyList) {
            String areaName = company.getAreaName();
            if ("華南".equals(areaName)) {
                areaStatistic.setSouthChina(areaStatistic.getSouthChina()+1);
                areaStatistic.setSouthChinaId(company.getAreaId());
            } else if ("華北".equals(areaName)) {
                areaStatistic.setNorthChina(areaStatistic.getNorthChina()+1);
                areaStatistic.setNorthChinaId(company.getAreaId());
            } else if ("華東".equals(areaName)) {
                areaStatistic.setEastChina(areaStatistic.getEastChina()+1);
                areaStatistic.setEastChinaId(company.getAreaId());
            }
        }
        System.out.println(areaStatistic);
        // 解法二
        AreaStatistic areaStatistic2 = new AreaStatistic();
        for (Company company:companyList) {
            setAreaProperty(areaStatistic2,company.getAreaName(),company.getAreaId());
        }
        System.out.println(areaStatistic2);

    }

    private void setAreaProperty(AreaStatistic areaStatistic,String areaName,Integer areaId) throws IllegalAccessException {
        Class staticClass = areaStatistic.getClass();
        Field[] fields = staticClass.getDeclaredFields();
        for (Field field : fields) {
            ColumnProperty property = field.getAnnotation(ColumnProperty.class);
            String value = property.value();
            if (value != null) {
                int indexOf = value.indexOf("大區(qū)");
                if (indexOf != -1 && value.length() == 4) {
                    if (areaName.equals(value.substring(0,2))) {
                        field.setAccessible(true);
                        field.set(areaStatistic,(Integer) field.get(areaStatistic) + 1);
                        for (Field idField : fields) {
                            ColumnProperty idProperty = idField.getAnnotation(ColumnProperty.class);
                            String idValue = idProperty.value();
                            if (idValue.equals(areaName+"id")) {
                                idField.setAccessible(true);
                                idField.set(areaStatistic,areaId);
                                break;
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    /**
     * 根據(jù)注解累加字段值
     */
    @Test
    public void accumulate() throws IllegalAccessException {
        AreaStatistic statistic = new AreaStatistic();
        statistic.setEastChina(2);
        statistic.setNorthChina(3);
        statistic.setSouthChina(1);
        int sum = 0;
        Class staticClass = statistic.getClass();
        Field[] fields = staticClass.getDeclaredFields();
        for (Field field : fields) {
            ColumnProperty property = field.getAnnotation(ColumnProperty.class);
            String value = property.value();
            if (value.indexOf("大區(qū)") != -1) {
                field.setAccessible(true);
                sum += field.get(statistic) == null ? 0 : (Integer) field.get(statistic);
            }
        }
        System.out.println(sum);
    }

}

到此這篇關(guān)于Java通過反射注解賦值的方法詳解的文章就介紹到這了,更多相關(guān)Java反射注解賦值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring boot項(xiàng)目中異常攔截設(shè)計(jì)和處理詳解

    Spring boot項(xiàng)目中異常攔截設(shè)計(jì)和處理詳解

    這篇文章主要介給大家紹了關(guān)于Spring boot項(xiàng)目中異常攔截設(shè)計(jì)和處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起看看吧
    2018-12-12
  • Java中Bigdecimal類的toString()方法和toPlainString()方法區(qū)別

    Java中Bigdecimal類的toString()方法和toPlainString()方法區(qū)別

    BigDecimal類有多個(gè)方法可以將其轉(zhuǎn)換為字符串,其中包括toString()和toPlainString(),本文主要介紹了Java中Bigdecimal類的toString()方法和toPlainString()方法區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • SpringBoot接收參數(shù)所有方式總結(jié)

    SpringBoot接收參數(shù)所有方式總結(jié)

    這篇文章主要介紹了SpringBoot接收參數(shù)所有方式總結(jié),文中通過代碼示例和圖文結(jié)合的方式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-07-07
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(37)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(37)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • 一篇文章帶你深入了解Java基礎(chǔ)

    一篇文章帶你深入了解Java基礎(chǔ)

    這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • 關(guān)于springboot整合swagger問題及解決方法

    關(guān)于springboot整合swagger問題及解決方法

    這篇文章主要介紹了關(guān)于springboot整合swagger問題及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Springboot AOP對指定敏感字段數(shù)據(jù)加密存儲(chǔ)的實(shí)現(xiàn)

    Springboot AOP對指定敏感字段數(shù)據(jù)加密存儲(chǔ)的實(shí)現(xiàn)

    本篇文章主要介紹了利用Springboot+AOP對指定的敏感數(shù)據(jù)進(jìn)行加密存儲(chǔ)以及對數(shù)據(jù)中加密的數(shù)據(jù)的解密的方法,代碼詳細(xì),具有一定的價(jià)值,感興趣的小伙伴可以了解一下
    2021-11-11
  • Java?Git?Commit?Message使用規(guī)范

    Java?Git?Commit?Message使用規(guī)范

    這篇文章主要介紹了Java?Git?Commit?Message使用規(guī)范,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助
    2022-08-08
  • 一篇文章從無到有詳解Spring中的AOP

    一篇文章從無到有詳解Spring中的AOP

    。Spring AOP 是基于 AOP 編程模式的一個(gè)框架,它的使用有效減少了系統(tǒng)間的重復(fù)代碼,達(dá)到了模塊間的松耦合目的,這篇文章主要給大家介紹了關(guān)于Spring中AOP的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Springboot視頻接口報(bào)大量的ClientAbortException找不到原因的解決

    Springboot視頻接口報(bào)大量的ClientAbortException找不到原因的解決

    本文主要介紹了Springboot視頻接口報(bào)大量的ClientAbortException找不到原因的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08

最新評論