码迷,mamicode.com
首页 > 编程语言 > 详细

Java笔记:注解

时间:2018-02-18 13:56:16      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:col   ted   基础   except   ide   语义   地方   reflect   try   

一、基础知识

Java支持在源文件中嵌入补充信息,这类信息称为注解(元数据)。注解不会改变程序的行为,因此也不会改变程序的语义。

 

二、声明

上述声明表示注解。注解都只能包含方法声明,不能为这些方法提供实现,而是由Java实现。所有的注解类型都自动扩展了Annotation接口,其指定了annotationType方法,该方法返回调用注解的对象。

在声明了注解之后就可以用来注解声明了。所有的声明都可以有与之关联的注解,甚至注解本身也可以被注解。使用注解时,需要为注解的成员提供值。

技术分享图片
class Solution {
    @interface MyAnnotation {
        String str();
        int val() default 0;//使用默认值
    }

    @MyAnnotation(str = "printHello", val = 1)
    public static void print() {
        System.out.println("Hello");
    }
}
View Code


三、指定保留策略

注解保留策略决定了在什么位置丢弃注解。Java于java.lang.annotation.RetentionPolicy枚举中定义了三种保留策咯:

  • SOURCE策略仅在源文件中保留注解而编译期抛弃。
  • CLASS策略在编译时将注解存储至class文件中但是Java虚拟机不能得到这些注解。
  • RUNTIME策略提供了永久的注解。
技术分享图片
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String str();
    int val();
}
View Code

 

四、使用反射获取注解

如果为注解指定RUNTIME保留策略,任何程序在运行的时候都可以使用反射来查询注解。反射时能够在运行时获取类相关信息的特性。

技术分享图片
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String str();

    int val();
}

class Solution {
    @MyAnnotation(str = "Annotation content", val = 0)
    public static void printAnnotation() {
        Solution ob = new Solution();
        try {
            Class<?> c = ob.getClass();
            Method method = c.getMethod("printAnnotation");
            MyAnnotation anno = method.getAnnotation(MyAnnotation.class);
            System.out.println(anno);
        } catch (NoSuchMethodException exc) {
            System.out.println("Method does not exist");
        }
    }

    public static void main(String[] args) {
        printAnnotation();
    }
}
View Code

获取所有注解。

技术分享图片
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotationA {
    String str();
}

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotationB {
    int val();
}

@MyAnnotationA(str = "Class annotation content")
@MyAnnotationB(val = 1)
class Solution {
    @MyAnnotationA(str = "Method annotation content")
    @MyAnnotationB(val = 0)
    public static void printAnnotation() {
        Solution ob = new Solution();
        try {
            Annotation[] annos = ob.getClass().getAnnotations();
            for (Annotation a : annos)
                System.out.println(a);

            Method method = ob.getClass().getMethod("printAnnotation");
            annos = method.getAnnotations();
            for (Annotation a : annos)
                System.out.println(a);
        } catch (NoSuchMethodException exc) {
            System.out.println("Method does not exist");
        }
    }

    public static void main(String[] args) {
        printAnnotation();
    }
}
View Code


五、相关接口

getAnnotation方法和getAnnotations方法均由AnnotatedElement接口定义,该接口支持注解反射。AnnotatedElement接口此外还定义了如下方法:

  • getDeclaredAnnotations方法返回调用对象中存在的所有非继承注解。
  • isAnnotationPresent方法返回注解与对象是否关联。

 

六、标记注解

标记注解是特殊类型的注解,其中不包含成员。标记注解的唯一目的就是标记声明,确定标记注解是否存在的最好方式是使用isAnnotationPresent方法。

技术分享图片
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface Marker {}

class Solution {
    @Marker
    public static void printAnnotation() {
        Solution ob = new Solution();
        try {
            Class<?> c = ob.getClass();
            Method method = c.getMethod("printAnnotation");
            System.out.println(method.isAnnotationPresent(Marker.class));
        } catch (NoSuchMethodException exc) {
            System.out.println("Method does not exist");
        }
    }

    public static void main(String[] args) {
        printAnnotation();
    }
}
View Code


七、单成员注解

单成员注解通常只包含一个成员,允许使用缩写形式指定成员值。该成员名称必须是value,若包含其他成员则必须有默认值。

技术分享图片
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface Single {
    String value();
    int i() default 0;
}

class Solution {
    @Single("printHello")
    public static void print() {
        System.out.println("Hello");
    }
}
View Code

 

八、内置注解

  • Retention指定保留策略,只能注解其他注解。
  • Documented是标记接口,通知其他工具注解将被文档化,只能注解其他注解。
  • Target指定可以应用注解的声明类型,只能注解其他注解。可同时指定多个值。
  • Inherited是标记注解,指明超类注解可被子类继承,只能注解其他注解。
  • Override是标记注解,指明必须重写超类中的方法,只能注解方法。
  • Deprecated是标记注解,指明声明是过时的,已被新的形式取代。
  • FunctionalInterface指明接口是函数式接口。函数式接口仅包含一个由lambda表达式所使用的抽象方法。
  • SafeVarargs是标记注解,指明没有发生与可变长度参数相关的不安全动作,只能用于方法和构造函数。
  • SuppressWarnings指明抑制编译器可能会报告的警告,使用字符串表示警告名称。

 

九、类型注解

最早的注解只能应用于声明,但是现在已经能应用于使用类型的大多数地方。扩展后的这种注解称为类型注解。类型注解允许工具对代码执行额外检查,从而帮助避免错误。

技术分享图片
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.CONSTRUCTOR)
@interface ConstructorAnno {}

@Target(ElementType.TYPE_USE)
@interface TypeAnno {}

@Target(ElementType.TYPE_PARAMETER)
@interface ParameterAnno {}

@Target(ElementType.FIELD)
@interface FieldAnno {}

class Solution<@ParameterAnno T> {
    @FieldAnno
    @TypeAnno
    private T data;

    @ConstructorAnno
    Solution(@TypeAnno T data) {
        this.data = data;
    }
}
View Code

 

Java笔记:注解

标签:col   ted   基础   except   ide   语义   地方   reflect   try   

原文地址:https://www.cnblogs.com/arseneyao/p/8450458.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!