天天看點

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)