zoukankan      html  css  js  c++  java
  • java自定义注解

    参考博客:https://blog.csdn.net/briblue/article/details/73824058

    感觉这篇文章写得非常好,讲的很清楚明白,易于理解;例子也很不错,做个记录:

    代码:

    package com.cy.test;
    
    import java.lang.annotation.*;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * 自定义注解测试类
     */
    @MyAnnotation(id = 100, msg = "hello annotation")
    public class TestAnnotation{
    
        @Check("hi")
        private int a;
    
        @Perform
        public void testMethod(){
    
        }
    
        public static void main(String[] args) {
            //获取类上的注解
            TestAnnotation t = new TestAnnotation();
            boolean r = t.getClass().isAnnotationPresent(MyAnnotation.class);//是否应用了某个注解
            System.out.println(r);
    
            if(r){
                MyAnnotation a = t.getClass().getAnnotation(MyAnnotation.class);//获取Annotation对象
                System.out.println("id:" + a.id());
                System.out.println("msg:" + a.msg());
            }
    
            Annotation annotation[] = t.getClass().getAnnotations();    //获取所有注解
            for(Annotation an : annotation){
                System.out.println(an.annotationType());   //获取注解类型:interface com.cy.test.MyAnnotation
            }
    
    
            //获取成员变量上的注解
            Field fields[] = t.getClass().getDeclaredFields();
            Field fielda = null;
            for(Field f : fields){
                System.out.println(f.getName() +"," +f.getType() +"," + f.getGenericType() + "," + f.getModifiers());
                if(f.getName().equals("a")) fielda = f;
            }
            fielda.setAccessible(true);
            Check check = fielda.getAnnotation(Check.class);
            System.out.println("check value:"+check.value());
    
    
            //获取方法上的注解
            try {
                Method testMethod = t.getClass().getDeclaredMethod("testMethod");
                Annotation annotations[] = testMethod.getAnnotations();
                for(Annotation a : annotations) {
                    System.out.println(a.annotationType().getSimpleName());
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
    
    
        }
    }
    
    /**
     * 自定义的注解  类上
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Target(ElementType.TYPE)
    @interface MyAnnotation {
        int id() default 0;
    
        String msg() default "defaule msg";
    
    }
    
    /**
     * 注解  属性上
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface Check {
        String value();
    }
    
    /**
     * 注解  方法上
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface Perform {
    
    }
    View Code

    console:

    true
    id:100
    msg:hello annotation
    interface com.cy.test.MyAnnotation
    a,int,int,2
    check value:hi
    Perform

    @Retention

    Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。

    它的取值如下: 

    - RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。 
    - RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。 
    - RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。

    我们可以这样的方式来加深理解,@Retention 去给一张标签解释的时候,它指定了这张标签张贴的时间。@Retention 相当于给一张标签上面盖了一张时间戳,时间戳指明了标签张贴的时间周期。

    @Target

    你可以这样理解,当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。

    类比到标签,原本标签是你想张贴到哪个地方就到哪个地方,但是因为 @Target 的存在,它张贴的地方就非常具体了,比如只能张贴到方法上、类上、方法参数上等等。@Target 有下面的取值

    • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解

    • ElementType.CONSTRUCTOR 可以给构造方法进行注解

    • ElementType.FIELD 可以给属性进行注解

    • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解

    • ElementType.METHOD 可以给方法进行注解

    • ElementType.PACKAGE 可以给一个包进行注解

    • ElementType.PARAMETER 可以给一个方法内的参数进行注解

    • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举

    另外,上面例子代码中f.getModifiers()得到的是2,为什么?

    JAVA 反射机制中,Field的getModifiers()方法返回int类型值表示该字段的修饰符。

    其中,该修饰符是java.lang.reflect.Modifier的静态属性。

    对应表如下:

    PUBLIC: 1
    PRIVATE: 2
    PROTECTED: 4
    STATIC: 8
    FINAL: 16
    SYNCHRONIZED: 32
    VOLATILE: 64
    TRANSIENT: 128
    NATIVE: 256
    INTERFACE: 512
    ABSTRACT: 1024
    STRICT: 2048

  • 相关阅读:
    移动硬盘无法识别提示需要格式化的解决办法
    Cassandra 入门(资料收集)
    [转] NoSQL生态系统
    软件项目实施问题收集(LastUpdatedOn:20141117)
    Sql server 收缩日志
    关于重构需要了解的一些原则
    C#定时任务采用线程和队列实现
    [转]我是如何带领团队开发项目的
    ASP.NET MVC 多套皮肤解决方案
    Mysql 问题汇总(不断更新中...)
  • 原文地址:https://www.cnblogs.com/tenWood/p/9497958.html
Copyright © 2011-2022 走看看