返回顶部
首页 > 资讯 > 后端开发 > Python >Java通过反射注解赋值的方法详解
  • 280
分享到

Java通过反射注解赋值的方法详解

2024-04-02 19:04:59 280人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录问题描述最终解决if/else 普通解法通过反射注解赋值属性解题思路汇总某些字段的和总结源码前段时间,领导分配一个统计销售区域汇总的数据,解决方案使用到了反射获取注解,通过注解获

前段时间,领导分配一个统计销售区域汇总的数据,解决方案使用到了反射获取注解,通过注解获取属性或者设置字段属性。

问题描述

查询公司列表,分别是公司id、区域id、区域名称:

公司id区域id区域名称
11华南
22华北
32华北
43华东
53华东

创建公司类Company

public class Company {

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

    
    private Integer id;

    
    private Integer areaId;

    
    private String areaName;
     
    // 省略get/set方法 

}

最终解决

要求汇总各个区域公司数量,得到如下汇总:

区域id区域名称公司总数
1华南1
2华北2
3华东2

最终区域实体AreaStatistic:

public class AreaStatistic {

    @ColumnProperty("华东大区")
    private Integer eastChina = 0;

    @ColumnProperty("华东id")
    private Integer eastChinaId;

    @ColumnProperty("华南大区")
    private Integer southChina = 0;

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

    @ColumnProperty("华北大区")
    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

这种做法的缺点:

  • 要写大量的条件判断语句,非常的繁琐。
  • 增加和减少统计区域,都要修改代码。

针对上面的缺点,使用反射获取注解,通过注解获取属性赋值。

通过反射注解赋值属性

解题思路

1.遍历公司列表,获取到区域id和区域名称。

2.创建自定义注解@ColumnProperty:

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

    String value() default "";

}

3.通过反射获取属性,然后遍历字段属性获取注解。

AreaStatistic字段属性上添加注解:

@ColumnProperty("华东大区")
private Integer eastChina = 0;

@ColumnProperty("华东id")
private Integer eastChinaId;

@ColumnProperty("华南大区")
private Integer southChina = 0;

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

@ColumnProperty("华北大区")
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.匹配区域名称和字段属性,比如遍历公司区域是华东,就遍历到华东大区注解对应的字段,并赋值或者获取字段值。

if (value != null) {
    int indexOf = value.indexOf("大区");
    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.区域id赋值也是相同的解题思路。

根据上面的思路,有如下代码汇总:

// 遍历公司
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("大区");
            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

汇总某些字段的和

上面算出各个区域的汇总之后,还要算出全部区域的总和,这里还是使用到注解,把属性字段包含大区都累加起来:

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("大区") != -1) {
        field.setAccessible(true);
        sum += field.get(statistic) == null ? 0 : (Integer) field.get(statistic);
    }
}
System.out.println(sum);

输出结果:

6

总结

1.自定义注解,通过反射获取注解

2.通过匹配注解值,获取或者复制对应的字段属性。

赋值主要代码为:

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;


public class SetValueByAnnotation {

    
    @Test
    public void test() throws IllegalAccessException {
        // 添加数据
        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("大区");
                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;
                    }
                }
            }
        }
    }

    
    @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("大区") != -1) {
                field.setAccessible(true);
                sum += field.get(statistic) == null ? 0 : (Integer) field.get(statistic);
            }
        }
        System.out.println(sum);
    }

}

到此这篇关于Java通过反射注解赋值的方法详解的文章就介绍到这了,更多相关Java反射注解赋值内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java通过反射注解赋值的方法详解

本文链接: https://lsjlt.com/news/164936.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java通过反射注解赋值的方法详解
    目录问题描述最终解决if/else 普通解法通过反射注解赋值属性解题思路汇总某些字段的和总结源码前段时间,领导分配一个统计销售区域汇总的数据,解决方案使用到了反射获取注解,通过注解获...
    99+
    2024-04-02
  • Java通过反射,如何动态修改注解的某个属性值
    Java反射动态修改注解的某个属性值 昨晚看到一条问题,大意是楼主希望可以动态得建立多个Spring 的定时任务。 这个题目我并不是很熟悉,不过根据题目描述和查阅相关Spring 创...
    99+
    2024-04-02
  • Java方法反射实现原理详解
    博主说:Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。在本文中,占小狼分析了 J...
    99+
    2023-05-31
    java 方法反射 ava
  • Java通过反射来打印类的方法实现
    目录一. 案例出发二. 反射方法的分析2.1 反射的方式2.2 修饰符的打印2.3 getDeclaredxxx和getxxx的区别2.4 getSimpleName和getName...
    99+
    2024-04-02
  • java中反射和注解的简单使用方法
    目录什么反射?Java反射机制提供的功能反射相关的主要APIClass 类获取Class 类的实例( 四种方法)哪些类型可以有Class 对象?演示Class类的常用方法有了Clas...
    99+
    2024-04-02
  • java使用反射给对象属性赋值的两种方法
    目录前言方法1:这里使用了Field的set方的 Field 属性,然后设置可见性,然后设置了一个值,最后打印方法2:使用invoke方法总结:前言 最近项目中遇到一个问题,就是能实...
    99+
    2023-05-14
    java用反射给属性赋值 java反射设置属性的值 java 反射属性
  • java中怎么通过反射获取字段的值
    通过反射获取字段的值,可以使用Java中的Field类的get()方法。首先,需要获取字段对应的Class对象,然后再通过Class...
    99+
    2023-09-27
    java
  • Java反射的定义和用法详解
    目录定义获取Class对象1.1 通过类名获取Class对象1.2 通过对象获取Class对象1.3 通过类字面常量获取Class对象获取类的信息2.1 获取所有字段2.2 获取指定...
    99+
    2023-05-18
    Java反射 Java反射操作
  • Golang反射获取变量类型和值的方法详解
    目录1. 什么是反射2. reflect.Type2.1 类型Type和种类Kind2.2 引用指向元素的类型2.3 结构体成员类型3. reflect.Value3.1 结构体的成...
    99+
    2022-12-08
    Golang反射获取变量类型 值 Golang反射获取变量类型 Golang反射获取值 Golang反射
  • 详解C#通过反射获取对象的几种方式比较
    目录使用标准反射的 Invoke 方法使用 Activator.CreateInstance使用 Microsoft.Extensions.DependencyInjectionNa...
    99+
    2024-04-02
  • Java的枚举,注解和反射(一)
    目录枚举什么是枚举?枚举类的实现自定义实现枚举类使用关键字enum定义枚举类Enum的常用方法实现接口的枚举类注解注解概述常见的注解总结枚举 什么是枚举? 枚举的字面意思就是 一一列...
    99+
    2024-04-02
  • Java的枚举,注解和反射(二)
    目录反射什么是反射?反射的用途反射的具体作用反射的主要APIClass类总结反射 什么是反射? 反射是指在程序运行期间,可以通过Reflection Api提供方法可以获取任何类的内...
    99+
    2024-04-02
  • Java中的反射机制详解
    目录一、什么是反射?二、为什么要用反射三、Class类四、获取Class类对象的四种方式五.通过反射构造一个类的实例①使用Class.newInstance②通过反射先获取构造方法再...
    99+
    2024-04-02
  • java反射之Method的invoke方法实现教程详解
    反射是Java语言的一种特性,它可以在运行时动态地获取类的信息并操作类的成员。Method类是反射机制中用于表示方法的类,在Meth...
    99+
    2023-08-17
    Java
  • JAVA基础之注解与反射的使用方法和场景
    目录注解注解定义使用场景内置注解 元注解反射加载配置文件反射获取Class反射获取 Constructor反射获取 Method反射获取 Field通过反射获取注解信息内省...
    99+
    2024-04-02
  • java反射调用方法NoSuchMethodException的解决方案
    目录java反射调用方法NoSuchMethodExceptionNoSuchMethodException问题总结1、编译异常,这个很容易发现并解决2、编译正常,运行报错java反...
    99+
    2024-04-02
  • Java 反射机制的实例详解
    Java 反射机制的实例详解前言 今天介绍下Java的反射机制,以前我们获取一个类的实例都是使用new一个实例出来。那样太low了,今天跟我一起来学习学习一种更加高大上的方式来实现。正文 Java反射机制定义Java反射机制是指在运行状态中...
    99+
    2023-05-31
    java 反射机制 ava
  • java怎么通过反射获得方法真实参数名
    今天小编给大家分享一下java怎么通过反射获得方法真实参数名的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。示例咱们先来看这样...
    99+
    2023-06-29
  • java高级用法之注解和反射讲义
    前言 反射和注解在java中偏高级用法,一般在各种框架中被广泛应用,文章简单介绍下反射和注解的用法,希望对你的工作学习有一定帮助 java注解 什么是注解 Java 注解也就是An...
    99+
    2024-04-02
  • Java 用反射设置对象的属性值实例详解
    Java 用反射设置对象的属性值实例详解private Object invoke(Object obj, String fieldName, Object value) { String firstWord = fieldName.su...
    99+
    2023-05-31
    java 反射 对象
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作