java元注解详解及自定义注解的方法

什么是注解

注解相当于一种标记,开发工具、编译器、JVM可以通过反射来了解类和元素有没有注解,
然后去做出相应的操作。
例如 重写方法时加上@Override注解,编译器就会检查该方法有没有正确的覆盖方法

修饰注解的注解:元注解

Retention注解

Retention注解用于限制注解信息保留的阶段

@Retention注解有一个属性value是RetentionPolicy类型的。
RetentionPolicy 有3个枚举值:SOURCE CLASS RUNTIME
* @RetentinoPolicy(RetentionPolicy.SOURCE) 修饰注解时,该注解的信息只会保留
在源文件中,不会保留在class文件中,也不会被jvm读取到运行时
* @RetentionPolicy(RetentionPolicy.CLASS) 修饰注解时,该注解的信息会保留在
class文件中,但是不会被jvm读取
* @RetentionPolicy(RetentionPolicy.RUNTIME) 修饰注解时,该注解的信息会被保留
在class文件中,也会被jvm读取从而保留到运行时

Target注解

Target注解限定注解适用的类型
Target的value属性是一个ElementType枚举类。
枚举值有7个:
1. ElementType.CONSTRUCTOR —注解可以用于构造器
2. ElementType.FIELD —注解可以用于域声明
3. ElementType.LOCAL_VARIABLE — 注解可以用于局部变量声明
4. ElementType.METHOD — 注解可以用于方法声明
5. ElementType.PACKAGE — 注解可以用于包声明
6. ElementType.PARAMETER — 注解可以用于参数
7. ElementType.TYPE —注解可以用于类、接口、注解类型、enum声明

Documented注解

Documented注解表明制作javadoc时,是否将注解信息加入文档。如果注解在声明时
使用了@Documented,则在制作javadoc时会将注解信息加入javadoc.

Inherited注解

表明注解是否会被子类继承。默认情况子类不继承父类注解。
当一个注解加了@Inherited元注解后,该注解会被使用了该注解的子类继承

自定义注解的方法

定义注解类型跟一个定义一个接口类似
在interface关键字前面加一个@符号
注释中的每一个方法定义了这个注释类型的一个元素,
注释中方法的声明中一定不能包含参数,也不能抛出异常。
方法的返回值被限定为基本类型、String、Class、enums、注释以及这些类型的数组类型
方法可以有缺省值

自定义注解的例子

public @interface RequestForEnhancement{
    int id();
    String synopsis();
    String engineer() default "[unassigned]";
    String date(); default "[unimplemented]";
}

注解的用法:

@后面加注解名字,后面再跟上括号,括号中列出这个注释中的元素以及对应
的值的列表。键值对中的值必须是常量。

使用注解的例子

@RequestForEnhancement{id=20142480117,synopsis="Enable time-travel",engineer="Mr.liu",date="4/1/3007"}

标记型注解

如果注解没有元素,则该注解为标记型注解(maker)。

标记型注解例子:

public @interface Test{}

在使用标记型注解时,后面的括号可以忽略。

只有一个元素的注解

如果注解只有一个元素,则该元素的名字应该为value
使用该注解时元素的名字和等号可以省略

用自定义注解实现一个简单的测试框架

  1. 定义注解Test
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test{}
  1. 在要测试的方法上加@Test注解
public claass TestCase{
    @Test
    public static void test1(){}
    @Test
    public static void test2(){
        System.out.println("test2");
    }
}
import java.lang.reflect.*;
public class TestCaseRun{
    public static void main(String args[]){
        Class clazz=TestCase.class;
        Method[] methods=clazz.getMethods();
        for(Method m:methods){
            if(m.isAnnotationPresent(Test.class){
                try{
                    m.invoke(null);
                }catch(Throwable ex){
                   System.out.println(ex.getCause());
                }
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章