java 之注解开发

一. 注解的基本概念
Java 注解就像修饰符一样,可以用于从java代码中抽取文档、跟踪代码中的依赖性或者在编译时做检查。
注解可以被应用在包、类、方法、成员变量、参数和本地变量的声明中;Java5.0定义了4个标准的meta-annotation类型,
它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited
这些类型和它们所支持的类在java.lang.annotation包中可以找到。下面我们看一下每个元注解的作用和相应分参数的使用说明

@Target:
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、
类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的
声明中使用了target可更加明晰其修饰的目标。
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
取值(ElementType)有:
    1.CONSTRUCTOR:用于描述构造器
    2.FIELD:用于描述域
    3.LOCAL_VARIABLE:用于描述局部变量
    4.METHOD:用于描述方法
    5.PACKAGE:用于描述包
    6.PARAMETER:用于描述参数
    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention
@Retention用来描述自定义注解的生命周期,其RetentionPoicy取值有: 
1. SOURCE:在源文件中有效 
2. CLASS:在class文件中有效 
3. RUNTIME:在运行时有效


使用示例:@Retention(RetentionPolicy.RUNTIME)
@Documented
@Documented用于表示自定义注解可以被javadoc之类的工具文档化,没有成员。
使用示例:@Documented


@Inherited
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的
annotation类型被用于一个class,则这个annotation将被用于该class的子类。@Inherited annotation类型是被标注过的
class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。
如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:
检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。
使用示例:@Inherited


JDK内置的标准注解
JavaSE中内置了三个标准注解,都是定义在java.lang中,它们是:
@Override:用于修饰子类的方法覆盖了父类中的方法;
@Deprecated:用于修饰已经过时了的方法,不推荐使用的方法;
@SuppressWarnnings:告诉java编译器禁止编译警告。


@Override
@Override很简单,只是一个标记,用于标注一个方法。它表示,被它标注的方法覆盖了父类的方法。如果一不小心,
子类的方法名写错了,有了@Override之后,编译时会报错。也就是说被@Override标注的方法如果没有覆盖父类的方法,编译时报错。


@Deprecated
@Deprecated也是一个标记注解,用于修饰一个方法。它表示此方法不推荐使用。无论是继承、覆盖或直接使用此方法,编译器都会给出警告。


@SuppressWarnings
字面翻译就是抑制警告,它用于告诉编译器,对被标注的这句代码不要给出特定的警告。
@SuppressWarnings有一些参数用于表示特定的警告:
deprecation:不要给出“不赞成使用的类或方法的警告”;
unchecked:不要给出“类型转换时警告”;
fallthrough:不要给出”switch语句块没有break的警告”;
path:不要给出“不存在的路径”的警告;
serial:不要给出“可序列化类缺少serialVersionUID”的警告;
finally:不要给出“finally语句块不能正常完成”的警告;
all:不要给出以上所有情况的警告。


代码案例

package annotation.demo1;


import java.lang.annotation.Documented;
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)
@Documented
public @interface Person {
    String name() default "msq";
    int age() default 18;
    String [] hobby() default{"basketball","football"};
}



package annotation.demo1;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StudentGender {
    public enum Gender{BOY,GIRL};
    Gender gender() default Gender.BOY;
}

package annotation.demo1;


import annotation.demo1.StudentGender.Gender;


@Person(name="zs",age=12,hobby={"test1","test2"})
public class Student {
    @StudentGender(gender=Gender.BOY)
    private String stuGender;


    public String getStuGender() {
        return stuGender;
    }


    public void setStuGender(String stuGender) {
        this.stuGender = stuGender;
    }

package annotation.demo1;

import java.lang.reflect.Field;
/**
 * 定义注解处理器
 * @author Administrator
 *
 */
public class AnnotationProcessor {
public static void getStudentInfo(Class<?> clazz){
    //如果指定类型的注释存在于此元素上,则返回 true,否则返回 false
    if(clazz.isAnnotationPresent(Person.class)){
        Person annotaion = (Person)clazz.getAnnotation(Person.class);
        System.out.println(annotaion);
        System.out.println(annotaion.age());
        System.out.println(annotaion.name());
        System.out.println(annotaion.hobby());
    }
 
        Field[] fields = clazz.getDeclaredFields();
        for(Field field :fields){
           System.out.println("fieldName=" + field.toString());
           if(field.isAnnotationPresent(StudentGender.class)){
               StudentGender annotation = (StudentGender)field.getAnnotation(StudentGender.class);
               System.out.println(annotation);
               System.out.println(annotation.gender());
           }
       }
    }
}
测试
package annotation.demo1;
public class TestDemo {
    public static void main(String[] args) {
        AnnotationProcessor.getStudentInfo(Student.class);
    }
}





猜你喜欢

转载自blog.csdn.net/ronin_88/article/details/77607352