博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(二) 注解语法
阅读量:4049 次
发布时间:2019-05-25

本文共 4071 字,大约阅读时间需要 13 分钟。

(1)一个注解是由一个注解接口定义的:

modifiers @interface AnnotationName{        element declaration1;        element declaration2;    }
 

(2)每个元素声明具有下面这种形式:

type elementName();    type elementName() default value;
 

例如,注解具有两个元素: assignedTo 和 severity

public @interface BugReport{        String assignedTo() default "[none]";        //int severity() = 0; 经测试不能使用 = 号,int类型也是default        int severity() default 0;    }

 

(3)每个注解都具有下面这种形式:
@AnnotationName(elementName1=value1, elementName2=value2, ...)
例 

@BugReport(assignedTo="Harry", serverity=10)

 其中元素的顺序无关紧要

例 

@BugReport(severity=10, assignedTo="Harry") 与上例相同

 

如果某个元素的值未指定,就使用声明的默认值。
如果某个元素的值未指定,且没有声明的默认值,则编译无法通过。
(4)有两个特殊的快捷方式可以用来简化注解。
标记注解:如果没有指定元素,可能因为注解中没有任何元素,或所有元素都使用默认值,此时可以补使用圆括号。这样的注解称为标记注解
例 

@BugReport

 

单值注解:如果一个元素具有特殊的名字value(该元素名必须为"value"),并且没有指定其他元素,那么就可以忽略掉这个元素名以及等号。

例 

@Target(ElementType.METHOD)    @Retention(RetentionPolicy.RUNTIME)    public @interface MyListener {        String value();    }
 

可以将这个注解写成如下形式:

@MyListener("string")
 

(5)所有的注解接口隐式的扩展java.lang.annotation.Annotation接口,这个接口是一个正规接口,而不是一个注解接口。

(6)无法扩展注解接口,换句话说,所有的注解接口都直接扩展直java.lang.annotation.Annotation。(但注解元素的类型可以为另一个注解)
(7)不用提供那些实现了注解接口的类,相反,虚拟机会在需要的时候产生一些代理类及对象。
例: 请求一个ActionListenerFor注解的时候,虚拟机实现了一个和下面相似的操作

return Proxy.newProxyInstance(classLoader, ActionListenerFor.class,        new InvocationHandler(){            public Object invoke(Object proxy, Method m, Object[] args) throws Throwable{                if(m.getName().equals("source")){                    return value of source annotation;                }                ...            }               }    });

 

(8)注解接口中的元素声明实际上是方法声明。一个注解接口的方法可以没有任何参数,没有任何throws语句,并且它们也不能是泛型的。
(9)注解元素的类型为下列之一
一个基本类型(int, short, long, byte, char, double, float或boolean)
一个String
一个Class(具有一个可供选择的类型参数,例如 Class<? extends MyClass> )
一个enum类型
一个注解类型
一个由前面所述类型组成的数组(由数组组成的数组不是合法的元素类型)
例  一些合法的元素声明的例子

public @interface BugReport{           enum Status {UNCONFIRMED, CONFIRMED, FIXED, NOTABUC};           boolean showStopper() default false;        String assignedTo() default "[none]";        Class
testCase() default Void.class; Status status() default Status.UNCONFIRMED; Reference ref() default @Reference(); //an annotation type String[] reportedBy(); }

 

(10)因为注解是由编译器计算而来的,因此,所有元素值必须是编译期常量。
例 

@BugReport(showStopper=true, assignedTo="Harry", testCase=MyTestCase.class,        status=BugReport.Status.CONFIRMED, reportedBy={"Harry", "Carl"}, ref=@Reference(id="123"))

 (11)一个注解元素从来不能设置为null,甚至不允许其默认值为null。这样在实际应用中会相当不方便,必须使用其他的默认值,例如 "" 或者 Void.class。

       
(12)如果元素值是一个数组,要将它的值用括号括起来
例 

@BugReport(..., reportedBy={"Harry", "Carl"})

 

如果该元素具有单值,可以忽略这些括号:

@BugReport(..., reportedBy="Joe") // "Joe" same as {"Joe"}
 

(13)一个注解元素可以是另一个注解,那么可以创建出任意复杂的注解。

例 

@BugReport(ref=@Reference(id="123")...)
 

(14)注意,在注解中引入循环依赖是一种错误,例如在BugReport具有一个注解类型为TestCase的元素,那么TestCase就不能再拥有一个类型为BugReport的元素。

(15)可以向注解中添加如下一些项:
类(包括enum)
接口(包括注解接口)
方法
构造器
实例成员(包含enum常量)
本地变量
参数变量
不过,对本地变量的注解只能在源码级别上进行处理,类文件无法描述本地变量,因此,所有的本地变量注解在编译完一个类的时候会被一起掉。同样地,对包的注解也只能在源码级别上进行处理。
注意:注解在文件package-info.java中,只包含包的声明,在这个文件中可以对包进行注解,这需要以注解为文件的开始。
(16)一个项可以具有多个注解,只要他们属于不同的类型即可。当注解一个特定项的时候,不能多次使用同一个注解类型。即对同一项使用多次相同的注解是错误的。
如果需要对一个项使用多次相同的注解,可以设计一个注解,它的值是一个由更简单的注解组成的数组。

@BugReports(@BugReport(showStopper=true, reportedBy="Joe"),        @BugReport(reportedBy={"Harry", "Carl"}))    void myMethod()
 

 

接口 java.lang.annotation.Annotation
Class<? extends Annotation> annotationType() : 返回此 annotation 的注解类型。用于描述该注解对象的注解接口。注意:调用注解对象上的getClass方法可以返回真正的类,而不是接口。
boolean equals(Object obj) : 如果指定的对象表示在逻辑上等效于此接口的注解,则返回 true。 即other是一个作为该注解对象来实现的同一注解接口的对象,并且该对象和other的所有元素彼此相等,则返回true
int hashCode() : 返回一个与equals方法兼容、由接口名以及元素名衍生出来的此 annotation 的哈希码,具体说明如下: 一个 annotation 的哈希码是其成员(包括那些带有默认值的成员)的哈希码的和,具体说明如下: annotation 成员的哈希码是成员值哈希码的 XOR(它是 String.hashCode() 计算得到的成员名哈希码的 127 倍),具体说明如下: 成员值的哈希码取决于其类型: 基值 v 的哈希码等于 WrapperType.valueOf(v).hashCode(),其中 WrapperType 是对应 v 的基本类型的包装器类型(Byte、Character、Double、Float、Integer、Long、Short 或 Boolean)。
String toString() : 返回此 annotation 的字符串表示形式。例如 @com.shaogq.annotation.mytest.MyListener(value=abc)

转载地址:http://mayci.baihongyu.com/

你可能感兴趣的文章
[关注大学生]李开复给中国计算机系大学生的7点建议
查看>>
[茶余饭后]10大毕业生必听得歌曲
查看>>
gdb调试命令的三种调试方式和简单命令介绍
查看>>
C++程序员的几种境界
查看>>
VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
查看>>
VUE-Vue.js之$refs,父组件访问、修改子组件中 的数据
查看>>
Vue-子组件改变父级组件的信息
查看>>
Python自动化之pytest常用插件
查看>>
Python自动化之pytest框架使用详解
查看>>
【正则表达式】以个人的理解帮助大家认识正则表达式
查看>>
性能调优之iostat命令详解
查看>>
性能调优之iftop命令详解
查看>>
非关系型数据库(nosql)介绍
查看>>
移动端自动化测试-Windows-Android-Appium环境搭建
查看>>
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>
Selenium-Switch与SelectApi接口详解
查看>>