`

(二) 注解语法

阅读更多

(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)

分享到:
评论

相关推荐

    批量删除注解工具

    开发这样一个工具需要对目标编程语言的语法有深入理解,因为每种语言的注解语法都有所不同。例如,在Java中,注解以`@`符号开始,后面跟着注解类型,如`@Override`或`@Deprecated`。而在Python中,注解通常以`#`开始...

    注解javademo演示

    注解的语法结构通常以`@`符号开始,后跟注解的名称。例如,`@Override`表示方法是重写父类的方法,`@Deprecated`表示某个API不再推荐使用。注解可以应用于类、接口、方法、变量等不同的程序元素上。 Java提供了三种...

    ictar#python-doc#New In Python:变量注解语法1

    原文地址:

    Java注解实现方式

    注解的语法结构通常由`@`符号开头,后跟注解的名称。例如,`@Override`表示方法应该覆盖父类的方法。注解可以包含元素(也称为参数),元素通过键值对的形式指定,如`@MyAnnotation(key=value)`。如果元素没有默认值...

    注解方式实现AOP编程

    在Spring中,我们可以使用`@Pointcut`注解来定义一个切点表达式,它使用了类似于正则表达式的语法。例如: ```java @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethods() {} ``` ...

    自定义注解

    #### 二、注解的用途 在现代软件开发中,注解主要应用于以下几个方面: - **元数据提供**:为代码添加额外的信息。 - **代码分析**:帮助IDE或构建工具进行代码分析。 - **框架集成**:例如Spring框架利用注解进行...

    Java注解学习

    注解本质上是一种特殊的语法,用于在代码中嵌入元数据。这些元数据可以是关于代码的任何信息,如作者、版本、测试状态等,也可以是更复杂的结构,如配置参数。注解不会改变代码的行为,而是供其他工具解析和使用,...

    入门级java 注解学习示例代码

    1. `RetentionPolicy.SOURCE`:只保留在源代码级别,编译后不会存在,一般用于编译时的语法检查。 2. `RetentionPolicy.CLASS`:默认策略,注解保留在.class文件中,但JVM运行时不处理。 3. `RetentionPolicy....

    Java注解编程1

    1. 自定义注解语法:自定义注解的成员变量类型有限制,只能是原始类型、String、Class、Annotation和枚举。可以设置默认值,若只有一个成员,推荐使用`value()`方法。注解成员必须无参且无异常声明。 2. 元注解应用...

    自定义注解使用

    自定义注解的定义语法类似于接口,但用`@interface`关键字来声明。下面是一个简单的自定义注解示例: ```java public @interface MyAnnotation { String value() default ""; } ``` 在这个例子中,`MyAnnotation`...

    编译时注解开发

    注解语法 注解由`@`符号开头,后面跟着注解的名称。可以有零个或多个参数,参数以键值对形式存在,例如: ```java @MyAnnotation(param1 = "value1", param2 = 2) ``` 注解可以应用于类、方法、字段、参数等多个...

    aixos-ts-encapsulation_自定义注解_

    1. **自定义注解**:在TypeScript中,自定义注解通过使用`@decorator`语法实现,其中`decorator`是一个函数,它接收类、方法、访问器、构造函数或参数作为参数。例如,你可以定义一个名为`Singleton`的装饰器,它会...

    java内置注解

    通过学习这些内置注解,你可以更好地理解Java的语法规则,提升代码的可读性、可维护性和安全性。同时,掌握这些注解的应用也能够帮助你编写出更加符合Java最佳实践的代码。在实际开发中,熟练运用注解不仅可以提高...

    java自定义注解实现由类自动生成表

    对于SQL Server和Oracle,生成的SQL语句可能略有不同,因为它们支持的数据类型和语法有所不同。 例如,对于一个简单的Java实体类: ```java @GenerateTable(tableName = "User", schemaName = "public") public ...

    汇编注解程序汇编语言自动添加注解

    然而,由于其语法复杂且难以理解,汇编语言的学习和使用往往需要深入的计算机体系结构知识。为了解决这个问题,出现了“汇编注解程序”,它能够帮助程序员在编写或分析汇编代码时添加注解,提高代码可读性和可维护性...

    hibernate基础 注解开发 检索

    HQL支持基本的SQL语法结构,并且还支持对象和集合的导航: ```java Session session = sessionFactory.openSession(); Query query = session.createQuery("from Customer where name = :name"); query....

    高中语文课内文言文注解汇编-高考语文.pdf

    4. 注解的具体内容:针对文言文中出现的生僻字、古汉语语法结构、成语典故、古文化知识等,提供详细的解释和解读。例如,解释“之乎者也”等虚词的用法,或者对特定历史事件的背景知识进行介绍。 5. 应用和实践:这...

    Java 和 Kotlin的注解以及切面实现方式

    - **定义注解**:Kotlin注解定义同样使用`@interface`,但语法更简洁: ```kotlin annotation class MyAnnotation(val value: String) ``` - **使用注解**:使用方式与Java相同,但Kotlin提供了更简洁的语法糖,...

Global site tag (gtag.js) - Google Analytics