java注解

转载,https://blog.csdn.net/huangshanchun/article/details/51226846

1.认识注解

注解也被称为元数据,那什么是元数据?所谓的元数据就是用来定义数据的数据,如类的属性和方法等这些都是类的元数据。注解想当与在代码做一些特殊的标记,这些注解可以在编译,类加载,运行时候不改变原有的逻辑的情况下,被读取,并执行相应的处理。 如下下面例子中Override注解所示
  1. public class Test {  
  2.   
  3.     /* 
  4.      这里的Override就是一个标记,也就是我们所说的注解,它标记toString()方法就是一个覆写父类中的方法,因此我们如果 
  5.     我们将toString()方法名字写错了,则编译器就会根据这个Override的注解标记提示出相应的错误 
  6.     */  
  7.     @Override   
  8.     public String toString()  
  9.     {  
  10.         return “”;  
  11.     }  
  12. }  
public class Test {

    /*
     这里的Override就是一个标记,也就是我们所说的注解,它标记toString()方法就是一个覆写父类中的方法,因此我们如果
    我们将toString()方法名字写错了,则编译器就会根据这个Override的注解标记提示出相应的错误
    */
    @Override 
    public String toString()
    {
        return "";
    }
}

注解类似于修饰符一样被使用,可以用于包,类构造方法,方法,成员变量,参数,局部变量。

2.系统定义三个内置注解以及四种元注解

注解的的语法比较简单,除了@符号使用之外,它基本与Java的固有语法一致。Java SE5内置了三种注解,定义在Java.lang中的注解:
@Override,表示当前的方法定义覆盖超类中的方法,如果你不小心拼写错误,或者方法签名对不上覆盖的方法,编译器就会发出错误提示。
@Deprecated 表示一个类或者方法以及过时,不建议再使用。如果程序员使用了它,编译器就会发出警告的信息。
@SuppressWarnings,关闭不当的编译警告信息。
下面我给出Override的注解类,JDK中定义源代码
  1. @Target(ElementType.METHOD)  
  2. @Retention(RetentionPolicy.SOURCE)  
  3. public @interface Override {  
  4. }  
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
四种元注解主要用来注解其它的注解
(1)@Target 表示该注解可以用于什么地方,也就是说其使用范围, 值得说明的事当属性名定义为value时候,在使用该注解的赋值的时候alue可以省略。
  1. @Documented  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. @Target(ElementType.ANNOTATION_TYPE)  
  4. public @interface Target {  
  5.     ElementType[] value();  
  6. }  
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}
枚举ElementType 主要成员,该成员用来描述枚举
  1. public enum ElementType {  
  2.     /** Class, interface (including annotation type), or enum declaration */  
  3.     TYPE,  
  4.   
  5.     /** Field declaration (includes enum constants) */  
  6.     FIELD,  
  7.   
  8.     /** Method declaration */  
  9.     METHOD,  
  10.   
  11.     /** Parameter declaration */  
  12.     PARAMETER,  
  13.   
  14.     /** Constructor declaration */  
  15.     CONSTRUCTOR,  
  16.   
  17.     /** Local variable declaration */  
  18.     LOCAL_VARIABLE,  
  19.   
  20.     /** Annotation type declaration */  
  21.     ANNOTATION_TYPE,  
  22.   
  23.     /** Package declaration */  
  24.     PACKAGE  
  25. }  
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE
}
@Retention 表示需要在什么级别上保存注解信息,SOURCE 注解将会编译器丢弃,也就是说其只在编译阶段起作用,如何Override只是在编译阶段起作用
CLASS 表示注解在class文件中可用,但在JVM中会丢弃。RUNTIME表示在运行时候注解依然可用。


  1. @Documented  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. @Target(ElementType.ANNOTATION_TYPE)  
  4. public @interface Retention {  
  5.     RetentionPolicy value();  
  6. }  
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}
RetentionPolicy枚举
  1. public enum RetentionPolicy {  
  2.     /** 
  3.      * Annotations are to be discarded by the compiler. 
  4.      */  
  5.     SOURCE,  
  6.   
  7.     /** 
  8.      * Annotations are to be recorded in the class file by the compiler 
  9.      * but need not be retained by the VM at run time.  This is the default 
  10.      * behavior. 
  11.      */  
  12.     CLASS,  
  13.   
  14.     /** 
  15.      * Annotations are to be recorded in the class file by the compiler and 
  16.      * retained by the VM at run time, so they may be read reflectively. 
  17.      * 
  18.      * @see java.lang.reflect.AnnotatedElement 
  19.      */  
  20.     RUNTIME  
  21. }  
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}
@Documented 注解表示的是文档化,可以生成doc文档的时候添加的注解,该注解是一个标记。
@Inherited 注解表示一个注解是否允许被其自己继承下来


3.自定义注解

注解的应用需要三个基本步骤:
(1).编写注解
(2).在类上应用注解
(3).对应用类注解类进行反射操作的类,因为只有这样才能让注解起作用
自定义的注解的语法如下:
访问控制权限 @interface 注解名{}
下面给出一个注解实例
  1. package com.ahu.annotation.test.demo;  
  2.   
  3. import java.lang.annotation.ElementType;  
  4. import java.lang.annotation.Retention;  
  5. import java.lang.annotation.RetentionPolicy;  
  6. import java.lang.annotation.Target;  
  7.   
  8. /* 
  9.  *自定义注解 
  10.  */  
  11. @Target(ElementType.TYPE)  
  12. @Retention(RetentionPolicy.RUNTIME)  
  13. public @interface MyAnnotation {  
  14.     public String name();//注解的属性,类似于方法的定义  
  15.     public String info() default “student”;  
  16.     public String[] like();//爱好  
  17.     public EnumSex sex();//性别  
  18. }  
package com.ahu.annotation.test.demo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*
 *自定义注解
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    public String name();//注解的属性,类似于方法的定义
    public String info() default "student";
    public String[] like();//爱好
    public EnumSex sex();//性别
}
在User类上使用注解

  1. package com.ahu.annotation.test.demo;  
package com.ahu.annotation.test.demo;
  1. /*使用自定义注解需要给相应的属性赋值,如何注解在定义的时候相应的属性已经给出了相应的缺省值,可以不用赋值,如info这个属性 
  2.  * like 数组赋值 
  3.  * sex 是枚举类型的数据赋值 
  4.  */  
  5. @MyAnnotation(name=“hsc”,like={“running”,“watch tv”},sex=EnumSex.MALE)  
  6. public class User {  
  7.     private String name;  
  8.   
  9.     public String getName() {  
  10.         return name;  
  11.     }  
  12.   
  13.     public void setName(String name) {  
  14.         this.name = name;  
  15.     }  
  16.       
  17. }  
/*使用自定义注解需要给相应的属性赋值,如何注解在定义的时候相应的属性已经给出了相应的缺省值,可以不用赋值,如info这个属性
 * like 数组赋值
 * sex 是枚举类型的数据赋值
 */
@MyAnnotation(name="hsc",like={"running","watch tv"},sex=EnumSex.MALE)
public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

  1. package com.ahu.annotation.test.demo;  
  2.   
  3. public enum EnumSex {  
  4. MALE,FEMALE  
  5. }  
package com.ahu.annotation.test.demo;

public enum EnumSex {
MALE,FEMALE
}
主函数入口测试类
  1. package com.ahu.annotation.test.demo;  
  2.   
  3. import java.lang.annotation.Annotation;  
  4.   
  5.   
  6. public class Test {  
  7.     public static void main(String []args)  
  8.     {  
  9.         try {  
  10.           
  11.             Class<?> c=Class.forName(”com.ahu.annotation.test.demo.User”);  
  12.             //获取类中标记中的所有类的标记 ,如何在类中标记可以class直接获取注解  
  13.             //如果在方法中标记可以通过获取方法拿到注解  
  14.             Annotation[] annotations=c.getAnnotations();  
  15.             for(Annotation a:annotations){  
  16.                 //判断是否是自己所指定的注解  
  17.                 if(c.isAnnotationPresent(MyAnnotation.class)){  
  18.                     MyAnnotation my=(MyAnnotation)a; //强制转换  
  19.                     System.out.println(my.name()); //输出注解内容  
  20.                     System.out.println(my.info());  
  21.                 }  
  22.               
  23.             }  
  24.         } catch (ClassNotFoundException e) {  
  25.             // TODO Auto-generated catch block  
  26.             e.printStackTrace();  
  27.         }  
  28.     }  
  29. }  
package com.ahu.annotation.test.demo;

import java.lang.annotation.Annotation;


public class Test {
    public static void main(String []args)
    {
        try {

            Class<?> c=Class.forName("com.ahu.annotation.test.demo.User");
            //获取类中标记中的所有类的标记 ,如何在类中标记可以class直接获取注解
            //如果在方法中标记可以通过获取方法拿到注解
            Annotation[] annotations=c.getAnnotations();
            for(Annotation a:annotations){
                //判断是否是自己所指定的注解
                if(c.isAnnotationPresent(MyAnnotation.class)){
                    MyAnnotation my=(MyAnnotation)a; //强制转换
                    System.out.println(my.name()); //输出注解内容
                    System.out.println(my.info());
                }

            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

注解离开了反射,它就变成了一个空架子。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值