zoukankan      html  css  js  c++  java
  • Java注解

    注解语法

    public @interface annationName{
        
    }
    

    元注解

    可以添加到注解上的注解,是一种基本注解
    

    元注解有@Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。

    @Retention

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

    @Documented

    和文档有关,能够将注解中的元素包含到 Javadoc 中去
    

    @Target

    指定了注解运用的地方
    

    取值:

    • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
    • ElementType.CONSTRUCTOR 可以给构造方法进行注解
    • ElementType.FIELD 可以给属性进行注解
    • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
    • ElementType.METHOD 可以给方法进行注解
    • ElementType.PACKAGE 可以给一个包进行注解
    • ElementType.PARAMETER 可以给一个方法内的参数进行注解
    • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举

    @Inherited

    Inherited 是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。
    说的比较抽象。代码来解释

    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    @interface Test {}
    
    
    @Test
    public class A {}
    
    
    public class B extends A {}
    
    

    注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解

    @Repeatable

    Repeatable 自然是可重复的意思。@Repeatable 是 Java 1.8 才加进来的,所以算是一个新的特性。

    什么样的注解会多次应用呢?通常是注解的值可以同时取多个。

    举个例子,一个人他既是程序员又是产品经理,同时他还是个画家。

    @interface Persons {
    	Person[]  value();
    }
    
    
    @Repeatable(Persons.class)
    @interface Person{
    	String role default "";
    }
    
    
    @Person(role="artist")
    @Person(role="coder")
    @Person(role="PM")
    public class SuperMan{
    	
    }
    
    

    注意上面的代码,@Repeatable 注解了 Person。而 @Repeatable 后面括号中的类相当于一个容器注解。

    什么是容器注解呢?就是用来存放其它注解的地方。它本身也是一个注解

    注解的属性

    注解的属性也叫做成员变量。注解只有成员变量,没有方法.注解的成员变量在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型
    

    注意:注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组

    注解中属性可以有默认值,默认值需要用 default 关键值指定。比如

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Annation1 {
        String value();
        int age() default 0;
    }
    

    java预置的注解

    Deprecated

    标注过时的方法、过时的类、过时的成员变量
    
    public class Annation2 {
        @Deprecated
        public void say1() {
            System.out.println("say hello1");
        }
    
        public void say2() {
            System.out.println("say hello2");
        }
        public static void main(String[] args){
         Annation2 annation2 = new Annation2();
         annation2.say1();
         annation2.say2();
        }
    }
    

    say1()方法调用时会显示一条划线,表示方法已过时,但不影响调用

    @Override

    提示子类要复写父类中被 @Override 修饰的方法
    

    @SuppressWarnings

    阻止警告的意思。之前说过调用被 @Deprecated 注解的方法后,编译器会警告提醒,而有时候开发者会忽略这种警告,他们可以在调用的地方通过 @SuppressWarnings 达到目的
    

    @SafeVarargs

    @FunctionalInterface

    函数式接口注解,这个是 Java 1.8 版本引入的新特性。函数式编程很火,所以 Java 8 也及时添加了这个特性。
    

    函数式接口 (Functional Interface) 就是一个具有一个方法的普通接口

    @FunctionalInterface
    public interface Runnable {
        /**
         * When an object implementing interface <code>Runnable</code> is used
         * to create a thread, starting the thread causes the object's
         * <code>run</code> method to be called in that separately executing
         * thread.
         * <p>
         * The general contract of the method <code>run</code> is that it may
         * take any action whatsoever.
         *
         * @see     java.lang.Thread#run()
         */
        public abstract void run();
    }
    
    

    注解的提取

    注解通过反射获取。首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解

    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
    

    然后通过 getAnnotation() 方法来获取 Annotation 对象。

    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
    

    或者是 getAnnotations() 方法。

    public Annotation[] getAnnotations() {}
    

    前一种方法返回指定类型的注解,后一种方法返回注解到这个元素上的所有注解

    如果获取到的 Annotation 如果不为 null,则就可以调用它们的属性方法了。比如

    @Annation1(value = "123",age = 12)
    public class TestAnnation1 {
        /**
         * 反射获取注解
         * @param args
         */
        public static void main(String[] args){
               boolean hasAnnation = TestAnnation1.class.isAnnotationPresent(Annation1.class);
               if (hasAnnation) {
                   Annation1 annation1 = TestAnnation1.class.getAnnotation(Annation1.class);
                   System.out.println("value="+annation1.value());
                   System.out.println("age="+annation1.age());
               }
        }
    }
    
  • 相关阅读:
    JavaSE--注解
    JavaSE--【JAVA】unicode为12288字符
    Spring--Spring 注入
    Spring--@configuration 和 @Bean
    JavaEE--分布式对象
    JavaSE--jdom解析之bom
    JavaEE--分布式与集群
    JavaEE--调用 WSDL -- httpclient 4.x.x
    JavaSE--RMI初识
    Redis--初识Redis
  • 原文地址:https://www.cnblogs.com/hzhh123/p/10622316.html
Copyright © 2011-2022 走看看