Annotation: 代码的修饰符

Table of Contents

简介: 是什么, 用途, 为什么有用

Annotation 是一种元数据(metadata),它本身不是代码,但提供了一些关于代码的数据。这些数据可以是限定代码的一些功能,也可以是增加一些功能。可以将它理解为代码的修饰符,将代码当作一个名词,则Annotation是一个形容词,它使这个名词更加准确、或限定为更小的范围。如红红的苹果,直接说苹果也行,但有了红红的这个形容词,就更加准确了。 Annotation可以向编译器提供一些信息,如检测错误(@Override)、消除编译告警(@SuppressWarning)。 编译期生成代码(@Junit)。运行期提供一些检查机制(@NonNull)。被框架广泛使用。 和comment一样,annotation也能够起到描述代码功能。但它还具有检查机制。 为什么是需要的?有些信息无法通过代码表达出来,此时通过Annotation可以很好的达到。

使用: 一个简单例子,如@Override。系统提供的annotation,做成列表

Java 预定义的annotation

name

description

@Deprecated

被修饰的元素已经被弃用,不应该再使用。编译器会打印一个告警,如果这个元素还被使用

@Override

被修饰元素会覆盖基类的定义。

@SuppressWarnings

消除一个编译告警。接受一个参数

@SafeVarargs

指明方法不会对varargs做不安全的操作。unchecked 告警会被抑制

@FunctionalInterface

被用作为函数式接口,java8引入

修饰其它annotation的annotation

@Retention

参数: RetentionPolicy.SOURCE, .CLASS, .RUNTIME. 表示这个annotation 会被保存的地方

@Documented

元素必须被javadoc文档化

@Target

参数:ElementType.METHOD, .ANNOTATION_TYPE, .CONSTRUCTOR, .FIELD, .LOCAL_VARIABLE,

.PACKAGE, .PARAMETER, .TYPE. 指定元素的类型。

@Inherited

这个annotation会被它修改的类型的子类继承

@Repeatable

可被多次应用在一个元素上

REF: https://docs.oracle.com/javase/tutorial/java/annotations/predefined.html

使用方法,以@Override为例。

class A {
    void foo(){
        System.out.println("Supper class");
    }
}
class A1 extends A {
    @Override
    void foo(){
        System.out.println("Sub class");
    }
}
class Test {
    public static void main(String[] args) {
        A a = new A1();
        a.foo();
    }
}

@Override确保被修饰方法确实是覆盖了一个基类的方法,而不是定义了一个新的方法(这种情况在方法名拼写错误时发生),或重载了一个方法(在参数类型错误时发生)。以下是一个方法名拼写错误的例子。原本想覆盖基类的foo方法,但却拼写错了,导致程序结果错误。通过@Override在编译器就可检测出来。

class A {
    void foo(){
        System.out.println("Supper class");
    }
}
class A1 extends A {
    void fooo(){
        System.out.println("Sub class");
    }
}
class Test {
    public static void main(String[] args) {
        A a = new A1();
        a.foo();
    }
}

定义新的annotation。 涉及到的语法, processor的编写(以及使用APT辅助编写)。

定义一个新的annotation包括两部分,annotation本身的定义,和 annotation processor的定义。 其中annotation本身的定义相当于给系统增加了一个annotaion类型。 annotation processor是来解析、处理这个annotation. 一个定义annotation的例子:

定义了一个名为Autocall的annotation,它有一个属性 msg(默认值为"")。@Rentention 说明它会在RUNTIME时使用,@Target说明它只能修饰方法。

使用这个annotaion,修饰Test的foo方法:

class Test {
    @Autocall
    public static foo() {

    }
    public static void main(String[] args) {
    }
}

这个annotation设计的作用是使被修饰方法自动被main函数调用。这个需要新增代码来实现,也即为这个annotation编写一个processor来实现。如果没有processor, annotation和comment没什么区别。

Annotation processor的例子:

import java.lang.annotation.*;
import java.lang.Class;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Autocall {
    String msg() default "";
}

class AutocallProcessor {
    static void process(Class cls) {
        try{
            Class anntCls= Class.forName("Autocall");
            for(Method mtd: cls.getDeclaredMethods()){
                Autocall annt = (Autocall)mtd.getDeclaredAnnotation(anntCls);
                if (annt != null) {
                    // call this Method.
                    try{
                        mtd.invoke(null);
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (ClassNotFoundException e){
            System.out.println("ClassNotFoundException");
            System.exit(1);
        }

    }
    @Autocall
    static void foo(){
        System.out.println("Foo called");
    }
    public static void main(String[] args) {
        try{
            process(Class.forName("AutocallProcessor"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();

        }
    }
}

在框架中的应用。如Junit中。

Junit中定义了@Test,被修饰的方法会被当作一个测试方法。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C/C++基础

web前端开发初学者十问集锦(3)

我们经常使用元素的width:100%和height:100%将元素的宽度和高度扩充至父元素的宽度和高度。但是前提是需要对其父元素显示设置宽度和高度,否则无效。

772
来自专栏Java Edge

解惑Java注解类型(待更新)理解Java注解基本语法注解与反射机制运行时注解处理器Java 8中注解增强

java注解是在JDK5时引入的新特性,鉴于目前大部分框架(如Spring)都使用了注解简化代码并提高编码的效率,因此掌握并深入理解注解对于一个Java工程师是...

521
来自专栏大数据架构

Java进阶(一)Annotation(注解)

Annotation是Java5开始引入的特性。它提供了一种安全的类似于注释和Java doc的机制。实事上,Annotation已经被广泛用于各种Java框架...

4127
来自专栏JMCui

Java 注解

    从JDK1.5开始,引入了源代码中的注解这一机制。注解使得 Java 源代码中不但可以包含功能性的实现代码,还可以包含元数据。

601
来自专栏用户2442861的专栏

css display table-cell

display 属性规定元素应该生成的框的类型,用的最多的就是display:block;显示 display:none;隐藏。

751
来自专栏别先生

Javascript设置广告和时间表和数组的学习

1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title></title> 5 </hea...

1975
来自专栏五毛程序员

java注解入门(含源码下载)

3365
来自专栏coding for love

CSS入门11-定位与覆盖

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

922
来自专栏javathings

Java 中如何自定义注解?

例子很简单,使用@interface,定义记日志的注解,通过反射读取这个注解,如果函数有标记这个注解,那么调用这个函数的时候,需要打印日志。

702
来自专栏老马寒门IT

03-移动端开发教程-CSS3新特性(下)

1. CSS3动画 1.1 过渡的缺点 transition的优点在于简单易用,但是它有几个很大的局限。 transition需要事件触发,所以没法在网页加载时...

33713

扫码关注云+社区