天天看点

java自定义注解、反射、泛型应用

一、Java自定义注解

1.自定义注解元注解

  • @Target
  • @Retention
  • @Documented
  • @Inherited

1)@Target

用于描述注解的范围,即注解在哪用。它说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)等。取值类型(ElementType)有以下几种:

  • CONSTRUCTOR:用于描述构造器
  • FIELD:用于描述域即类成员变量
  • LOCAL_VARIABLE:用于描述局部变量
  • METHOD:用于描述方法
  • PACKAGE:用于描述包
  • PARAMETER:用于描述参数
  • TYPE:用于描述类、接口(包括注解类型) 或enum声明
  • TYPE_PARAMETER:1.8版本开始,描述类、接口或enum参数的声明
  • TYPE_USE:1.8版本开始,描述一种类、接口或enum的使用声明

2) @Retention

用于描述注解的生命周期,表示需要在什么级别保存该注解,即保留的时间长短。取值类型(RetentionPolicy)有以下几种:

  • SOURCE:在源文件中有效(即源文件保留)
  • CLASS:在class文件中有效(即class保留)
  • RUNTIME:在运行时有效(即运行时保留)

3) @Documented

用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。它是一个标记注解,没有成员。

4) @Inherited

用于表示某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

2.注解应用代码

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


@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TenderGoodsAnnotations {

    //属性名称
    String name() default "";

    //属性类型
    String type() default "";

    //翻译
    String translate() default "";

    //数据格式
    String format() default "";

}
           

3. 注解应用

import com.shigongbang.mybatis.base.tools.business.TenderGoodsAnnotations;
import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
public class ZcBidPropertyTransferGoods{

    @TenderGoodsAnnotations(name = "address",translate = "地址")
    private String address;
}
           

4. 泛型、反射应用

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class GoodsDetailEncapsulation<T> {

    /**
     * 物资清单列表封装
     *
     * @param list 物资清单列表
     * @return
     * @throws Exception
     */
    public List<List<Map<String, Object>>> goodsDetails(List<T> list) throws Exception {
        List<List<Map<String, Object>>> result = new ArrayList<>();

        for (T t : list) {
            List<Map<String, Object>> obList = new ArrayList<>();
			
			//通过反射获取泛型对象属性文件流
            Field[] fields = t.getClass().getDeclaredFields();

            //数量标识(表示物资清单中有数量需要拼接单位)
            Object numValue = null;
            Object unitValue = null;


            for (int i = 0; i < fields.length; i++) {
                Map<String, Object> objMap = new HashMap<>();
                objMap.put("name", fields[i].getName());


                //获取属性value值
                String firstLetter = fields[i].getName().substring(0, 1).toUpperCase();
                String getter = "get" + firstLetter + fields[i].getName().substring(1);
                Method method = t.getClass().getMethod(getter, new Class[]{});
                Object value = method.invoke(t, new Object[]{});

				//获取自定义注解TenderGoodsAnnotations 是否存在
                boolean tenderGoodsAnnotations = fields[i].isAnnotationPresent(TenderGoodsAnnotations.class);

                if (tenderGoodsAnnotations) {

					//获取自定义注解TenderGoodsAnnotations中的translate属性
                    String translate = fields[i].getAnnotation(TenderGoodsAnnotations.class).translate();
                    objMap.put("translate", translate);

                    String name = fields[i].getAnnotation(TenderGoodsAnnotations.class).name();
                    if (StrUtil.isNotEmpty(name)) {
                        objMap.put("name", name);
                    }

                    String type = fields[i].getAnnotation(TenderGoodsAnnotations.class).type();

					//其他自己业务处理
                    if ("date".equals(type)) {
                        String formatDate = fields[i].getAnnotation(TenderGoodsAnnotations.class).format();
                        if (StrUtil.isNotEmpty(formatDate)) {
                            if (value != null && !"".equals(value)) {
                                Format format = new SimpleDateFormat(formatDate);
                                value = format.format(value);
                            }

                        }
                    }
                }
                objMap.put("value", value);
                if (value != null) {
                    obList.add(objMap);
                }

            }
            if (CollectionUtil.isNotEmpty(obList)) {
                result.add(obList);
            }

        }
        return result;
    }
}
           

5. 自定义泛型方法应用

//要处理的数据集合
List<ZcBidCarRentalGoods> carRentalGoods =new ArryList();

//声明自定义泛型类
GoodsDetailEncapsulation goodsDetailEncapsulation = new GoodsDetailEncapsulation<ZcBidPropertyTransferGoods>();

//泛型类中的方法调用
goodsDetailEncapsulation.goodsDetails(carRentalGoods)