Java注解赏析及自定义注解

  1. 看看注解什么样?
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}


@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}
  1. 注解到底是什么?
    • 是一个类
    • 是一种标记,使用@interface标识
    • 使用@xxx的形式标注其他类,java注解是附加在代码(注解)中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能,用来描述类或属性
    • 注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用
  2. JDK中的注解及相关讲解
    注解分为三类:
    • 元注解
      • 定义在java.lang.annotation包中,对其他注解进行注解
      • @Documented 标记生成javadoc
      • @Retention 注解的生命周期,使用枚举类RetentionPolicy标识
        • @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
        • @Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
        • @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
        public enum RetentionPolicy {
            /**
             * Annotations are to be discarded by the compiler.
             */
            SOURCE,
        
            /**
             * Annotations are to be recorded in the class file by the compiler
             * but need not be retained by the VM at run time.  This is the default
             * behavior.
             */
            CLASS,
        
            /**
             * Annotations are to be recorded in the class file by the compiler and
             * retained by the VM at run time, so they may be read reflectively.
             *
             * @see java.lang.reflect.AnnotatedElement
             */
            RUNTIME
        }
        
      • @Target 注解的目标
        • 如@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
      • @Inherited 注解的继承关系
    • 标准注解
      • @Override 标识为覆写超类方法
      • @Deprecated 标识为弃用的类/方法
      • @SuppressWarnings 标识抑制编译器发出特定警告
    • 一般注解
      • @Component
      • @Service
      • 自定义注解
            package com.abuge.demo00001;
            
            import java.lang.annotation.Documented;
            import java.lang.annotation.ElementType;
            import java.lang.annotation.Retention;
            import java.lang.annotation.RetentionPolicy;
            import java.lang.annotation.Target;
            /**
             * 
             * 自定义注解,用于描述字段、方法信息
             *
             */
            @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在且在运行时可以通过反射获取到
            @Target({ ElementType.FIELD, ElementType.METHOD }) // 定义注解的作用目标及作用范围为声明的属性(包括枚举常量)、方法
            @Documented // 该注解被包含在javadoc中
            public @interface FieldMeta {
            
                boolean id() default false; //是否为序列号
            
                String name() default ""; //字段名称
            
                boolean editable() default true; //是否可编辑
            
                boolean summary() default true; //是否在列表中显示
            
                String description() default ""; //字段描述
            
                int order() default 0; //排序字段
            
            }
            
            
            package com.abuge.demo00001;
            /**
             * 使用注解
             *
             */
            public class Anno {
                @FieldMeta(id = true, name = "序列号", order = 1)
                private int id;
                @FieldMeta(name = "姓名", order = 3)
                private String name;
                @FieldMeta(name = "年龄", order = 2)
                private int age;
            
                @FieldMeta(description = "描述", order = 4)
                public String desc() {
                    return "java反射获取方法的注解测试";
                }
            
                public int getId() {
                    return id;
                }
            
                public void setId(int id) {
                    this.id = id;
                }
            
                public String getName() {
                    return name;
                }
            
                public void setName(String name) {
                    this.name = name;
                }
            
                public int getAge() {
                    return age;
                }
            
                public void setAge(int age) {
                    this.age = age;
                }
            }
            
            
            package com.abuge.demo00001;
            
            /**
             * 
             * 字段/方法注解业务类
             *
             */
            public class SortableField {
            
                private FieldMeta meta;
            
                private String name;
            
                private Class<?> type;
            
                public SortableField() {
                }
            
                public SortableField(FieldMeta meta, String name, Class<?> type) {
                    super();
                    this.meta = meta;
                    this.name = name;
                    this.type = type;
                }
            
                public FieldMeta getMeta() {
                    return meta;
                }
            
                public String getName() {
                    return name;
                }
            
                public Class<?> getType() {
                    return type;
                }
            
                public void setMeta(FieldMeta meta) {
                    this.meta = meta;
                }
            
                public void setName(String name) {
                    this.name = name;
                }
            
                public void setType(Class<?> type) {
                    this.type = type;
                }
            
            }
            
            
            
            package com.abuge.demo00001;
            
            import java.lang.reflect.Field;
            import java.lang.reflect.Method;
            import java.lang.reflect.ParameterizedType;
            import java.util.ArrayList;
            import java.util.Collections;
            import java.util.Comparator;
            import java.util.List;
            /**
             * 
             * 注解信息获取基类
             *
             */
            public class Parent<T> {
            
                Class<T> entity;
            
                @SuppressWarnings("unchecked")
                public List<SortableField> init() {
            
                    List<SortableField> fieldList = new ArrayList<SortableField>();
                    // 获得超类的泛型参数的实际类型
                    entity = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
            
                    if (null != entity) {
                        Field[] fields = entity.getDeclaredFields();
                        for (Field field : fields) {
                            FieldMeta meta = field.getAnnotation(FieldMeta.class);
                            if (null != meta) {
                                SortableField sortableField = new SortableField(meta, field.getName(), field.getType());
                                fieldList.add(sortableField);
                            }
                        }
            
                        Method[] methods = entity.getDeclaredMethods();
                        for (Method method : methods) {
                            FieldMeta meta = method.getAnnotation(FieldMeta.class);
                            if (null != meta) {
                                SortableField sortableField = new SortableField(meta, method.getName(), method.getReturnType());
            
                                fieldList.add(sortableField);
                            }
                        }
            
                        Collections.sort(fieldList, new Comparator<SortableField>() {
            
                            @Override
                            public int compare(SortableField o1, SortableField o2) {
                                return o1.getMeta().order() - o2.getMeta().order();
                            }
            
                        });
                    }
                    return fieldList;
                }
            }
            
            
            package com.abuge.demo00001;
            
            public class Child extends Parent<Anno> {
            
            }
            
            
            package com.abuge.demo00001;
            
            import java.util.List;
            /**
             * 测试类
             * @author huxianyang
             *
             */
            public class AnnotaionTest {
                public static void main(String[] args) {
                    Parent<?> child = new Child();
                    List<SortableField> fields = child.init();
                    for (SortableField f : fields) {
                        System.out.println("字段名称:" + f.getName() + "\t字段类型:" + f.getType() + "\t\t注解名称:" + f.getMeta().name()
                                + "\t注解描述:" + f.getMeta().description());
                    }
                }
            }
            
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容