• 注解


    @Target:设置该注解的应用场合。

    • value:ElementType[]
      • PACKAGE
        包定义
      • TYPE
        类/接口/注解/枚举 + 定义
      • ANNOTATION_TYPE
        注解定义
      • TYPE_PARAMETER
        泛型定义
      • TYPE_USE
        类/接口/注解/枚举/泛型 + 定义/应用
      • FIELD
        字段定义
      • CONSTRUCTOR
        构造器定义
      • METHOD
        方法定义
      • PARAMETER
        参数定义
      • LOCAL_VARIABLE
        局部变量定义

    用例1:注解包定义

    test/Test.java

    public class Test {
        public static void main(String[] params) {
            Annotation[] annotations = Package.getPackage("test").getAnnotations();
            System.out.println(Arrays.toString(annotations));
            // 输出结果:[@test.Test$TestAnnotation()]
        }
        
        @Target(ElementType.PACKAGE)
        @Retention(RetentionPolicy.RUNTIME)
        public static @interface TestAnnotation {
    
        }
    }

    test/package-info.java

    @test.Test.TestAnnotation
    package test;

    用例2:注解类/接口/注解/枚举 + 定义

    public class Test {
        public static void main(String[] params) {
            System.out.println(Arrays.toString(MyClass.class.getAnnotations()));
            System.out.println(Arrays.toString(MyInterface.class.getAnnotations()));
            System.out.println(Arrays.toString(MyAnnotation.class.getAnnotations()));
            System.out.println(Arrays.toString(MyEnum.class.getAnnotations()));
            
            /*
                输出结果:
                [@test.Test$TestAnnotation(value=类定义)]
                [@test.Test$TestAnnotation(value=接口定义)]
                [@test.Test$TestAnnotation(value=注解定义)]
                [@test.Test$TestAnnotation(value=枚举定义)]
             */
        }
        
        @Target(ElementType.TYPE)
        @Retention(RetentionPolicy.RUNTIME)
        public static @interface TestAnnotation {
            String value();
        }
        
        @TestAnnotation("类定义")
        public class MyClass {
            
        }
    
        @TestAnnotation("接口定义")
        public interface MyInterface {
            
        }
    
        @TestAnnotation("注解定义")
        public @interface MyAnnotation {
            
        }
    
        @TestAnnotation("枚举定义")
        public enum MyEnum {
            
        }
        
        // 编译错误:不允许注解泛型
        /*public class MyGeneric<@TestAnnotation("泛型定义") T> {
            
        }*/
    }

    用例3:注解泛型定义

    public class Test {
        public static void main(String[] params) {
            System.out.println(Arrays.toString(MyGeneric.class.getTypeParameters()[0].getAnnotations()));
            
            /*
                输出结果:
                [@test.Test$TestAnnotation(value=泛型定义)]
             */
        }
        
        @Target(ElementType.TYPE_PARAMETER)
        @Retention(RetentionPolicy.RUNTIME)
        public static @interface TestAnnotation {
            String value();
        }
        
        public class MyGeneric<@TestAnnotation("泛型定义") T> {
            
        }
    }

    用例4: 注解类/接口/注解/枚举/泛型 + 定义/应用

    public class Test<@TestAnnotation("泛型定义") T> {
        public static void main(String[] params) throws NoSuchFieldException, SecurityException, NoSuchMethodException {
            test1();
            System.out.println("--------------------------------------------------------------------------");
            test2();
        }
    
        public static void test1(){
            System.out.println(Arrays.toString(MyClass.class.getAnnotations()));
            System.out.println(Arrays.toString(MyInterface.class.getAnnotations()));
            System.out.println(Arrays.toString(MyAnnotation.class.getAnnotations()));
            System.out.println(Arrays.toString(MyEnum.class.getAnnotations()));
            System.out.println(Arrays.toString(Test.class.getTypeParameters()[0].getAnnotations()));
            /*
                输出结果:
                [@test.Test$TestAnnotation(value=类定义)]
                [@test.Test$TestAnnotation(value=接口定义)]
                []
                [@test.Test$TestAnnotation(value=枚举定义)]
                [@test.Test$TestAnnotation(value=泛型定义)]
             */
        }
    
        @Target(ElementType.TYPE_USE)
        @Retention(RetentionPolicy.RUNTIME)
        public static @interface TestAnnotation {
            String value();
        }
    
        @TestAnnotation("类定义")
        public static class MyClass {
            // 注:可编译通过,但无实际效果
            @TestAnnotation("字段定义")
            private int myField;
        }
    
        @TestAnnotation("接口定义")
        public static interface MyInterface {
    
        }
    
        // 注:可编译通过,但无实际效果
        @TestAnnotation("注解定义")
        public static @interface MyAnnotation {
    
        }
    
        @TestAnnotation("枚举定义")
        public static enum MyEnum {
    
        }
        
        public static void test2() throws NoSuchFieldException, SecurityException, NoSuchMethodException{
            System.out.println(Arrays.toString(MySubClass.class.getAnnotatedSuperclass().getAnnotations()));
            System.out.println(Arrays.toString(MyImplClass.class.getAnnotatedInterfaces()[0].getAnnotations()));
            System.out.println(Arrays.toString(Test.class.getDeclaredField("myClassField").getAnnotatedType().getAnnotations()));
            System.out.println(Arrays.toString(Test.class.getDeclaredField("myInterfaceField").getAnnotatedType().getAnnotations()));
            System.out.println(Arrays.toString(Test.class.getDeclaredField("myEnumField").getAnnotatedType().getAnnotations()));
            System.out.println(Arrays.toString(Test.class.getDeclaredField("myGenericField").getAnnotatedType().getAnnotations()));
            /*
                输出结果:
                [@test.Test$TestAnnotation(value=类继承应用)]
                [@test.Test$TestAnnotation(value=接口实现应用)]
                [@test.Test$TestAnnotation(value=类定义字段应用)]
                [@test.Test$TestAnnotation(value=接口定义字段应用)]
                [@test.Test$TestAnnotation(value=枚举定义字段应用)]
                [@test.Test$TestAnnotation(value=泛型定义字段应用)]
             */
        }
        
        public static class MySubClass extends @TestAnnotation("类继承应用") MyClass {
            
        }
        
        public static class MyImplClass implements @TestAnnotation("接口实现应用") MyInterface {
            
        }
    
        // 注:可编译通过,但无实际效果
        @TestAnnotation("字段定义")
        private int myField;
        
        private @TestAnnotation("类定义字段应用") MyClass myClassField;
        
        private @TestAnnotation("接口定义字段应用") MyInterface myInterfaceField;
        
        private @TestAnnotation("枚举定义字段应用") MyEnum myEnumField;
        
        private @TestAnnotation("泛型定义字段应用") T myGenericField;
    }

     

    @Retention:设置目标注解的保留策略。

    • value:RetentionPolicy
      • SOURCE
        源文件
      • CLASS
        类文件
      • RUNTIME
        运行时

    @Inherited:表示目标注解用于类定义时,类的子类是否可继承该注解。

    @Repeatable:表示目标注解可以多次应用于同一个场合。

    • value():Class<? extends Annotation>

    @Documented:表示目标注解可被工具生成文档。

    @Override:表示目标方法是继承或实现而来的。

    @Deprecated:表示目标已不建议使用。

    @SuppressWarnings:过滤一些编辑器的警告。

    @InterfaceFunction:表示目标接口是一个接口函数式,只有一个未实现且非静态的方法,其它方法可以是默认或静态方法。

    不解之迷:照理说,这不应该出现的问题。

    public class Test {
        public static void main(String[] params) {
            System.out.println(Arrays.toString(TestClass.class.getAnnotatedSuperclass().getAnnotations()));
            
            // 输出结果:
            // AnnotationFormatError: Duplicate annotation
        }
        
        public static class TestSuperClass{
            
        }
        
        public static class TestClass extends @TestInterface2({@TestInterface1(1), @TestInterface1(2)}) TestSuperClass{
            
        }
        
        @Target({ ElementType.TYPE_USE })
        @Retention(RetentionPolicy.RUNTIME)
        public static @interface TestInterface1{
            int value();
        }
        
        @Target({ ElementType.TYPE_USE })
        @Retention(RetentionPolicy.RUNTIME)
        public static @interface TestInterface2{
            TestInterface1[] value();
        }
    }

      

    解决方案1:TestInterface1删除@Retention

    public class Test {
        public static void main(String[] params) {
            System.out.println(Arrays.toString(TestClass.class.getAnnotatedSuperclass().getAnnotations()));
            
            // 输出结果:
            // [@Test$TestInterface2(value=[@Test$TestInterface1(value=1), @Test$TestInterface1(value=2)])]
        }
        
        public static class TestSuperClass{
            
        }
        
        public static class TestClass extends @TestInterface2({@TestInterface1(1), @TestInterface1(2)}) TestSuperClass{
            
        }
        
        @Target({ ElementType.TYPE_USE })
        public static @interface TestInterface1{
            int value();
        }
        
        @Target({ ElementType.TYPE_USE })
        @Retention(RetentionPolicy.RUNTIME)
        public static @interface TestInterface2{
            TestInterface1[] value();
        }
    }

      

    解决方案2:在TestInterface1上使用@Repeatable

    public class Test {
        public static void main(String[] params) {
            System.out.println(Arrays.toString(TestClass.class.getAnnotatedSuperclass().getAnnotations()));
            
            // 输出结果:
            // [@Test$TestInterface2(value=[@Test$TestInterface1(value=1), @Test$TestInterface1(value=2)])]
        }
        
        public static class TestSuperClass{
            
        }
        
        public static class TestClass extends @TestInterface1(1) @TestInterface1(2) TestSuperClass{
            
        }
        
        @Target({ ElementType.TYPE_USE })
        @Retention(RetentionPolicy.RUNTIME)
        @Repeatable(TestInterface2.class)
        public static @interface TestInterface1{
            int value();
        }
        
        @Target({ ElementType.TYPE_USE })
        @Retention(RetentionPolicy.RUNTIME)
        public static @interface TestInterface2{
            TestInterface1[] value();
        }
    }
  • 相关阅读:
    asp.net中控件的enableviewstate属性 的设置
    一个怎样得到treeView值的小例子
    实现表格边框的样式表
    GridView的精妙使用
    无法向会话状态服务器发出会话状态请求。
    Microsoft Visual Studio 2008 快捷键大全
    我每天学习一句英语今天要学的是
    C语言学习心得
    怎么样把GridView里的数据导出到Excel里
    怎么样在c#程序中放音乐
  • 原文地址:https://www.cnblogs.com/hvicen/p/6259433.html
Copyright © 2020-2023  润新知