Java 注解

Posted Zview

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 注解相关的知识,希望对你有一定的参考价值。

  Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法。Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据。

    Annotation能被用来为某个程序元素(类、方法、成员变量等)关联任何的信息。需要注意的是,这里存在着一个基本的规则:Annotation不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的执行。另外,尽管一些annotation通过java的反射api方法在运行时被访问,而java语言解释器在工作时忽略了这些annotation。正是由于java虚拟机忽略了Annotation,导致了annotation类型在代码中是“不起作用”的; 只有通过某种配套的工具才会对annotation类型中的信息进行访问和处理。

三种内置的注解,在java.lang包中:

  • @Override
  • @Deprecated     表示修饰的内容已经过时了,不建议使用这个方法了。
  • @SupressWarnings 关闭不当的编译器警告信息

SupressWarnings 的参数是一个String数组,可以的取值有

           1.deprecation:使用了不赞成使用的类或方法时的警告;
    2.unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型; 
    3.fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
    4.path:在类路径、源文件路径等中有不存在的路径时的警告; 
    5.serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告; 
    6.finally:任何 finally 子句不能正常完成时的警告; 
    7.all:关于以上所有情况的警告

public @interface _Test {
}

在注解中可以包含一些元素,注解跟接口很相似,但是注解的元素可以指定默认值,没有元素的注解成为标记注解
注解可以定义到任意的位置上,使用的位置可以由@Target指定。

元注解

@Target 表示注解可以用于什么地方 在ElementType中

  • CONSTRUCTOR
  • FIELD
  • LOCAL_VARIABLE
  • METHOD
  • PACKAGE
  • PARAMETER
  • TYPE    类、接口、enum、注解的声明

@Retention 表示在什么级别保存注解信息,在RetentionPolicy中

  • SOURCE
  • CLASS
  • RUNTIME

@Documented 将此注解包含在javadoc中

@Inherited 允许子类继承父类的注解,是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。

 

注解中的元素只能是一下类型,默认值必须是确定的,不能是null:

  • 基本类型
  • String
  • Class
  • enum
  • Annatation,,也就是注解可以嵌套

注解的一个价值在于,对于RUNTIME的注解,可以通过反射机制来获得注解的信息对应的相关的值,完成相关操作

 

注解的赋值:

当元素的名字是value的时候,如果只想对这一个元素赋值,可以直接写,不用key=val的对儿

对于数组,使用{}赋值,多个参数使用逗号隔开,并且要使用 key=val的语法

 

关于反射读取注解:

 AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象之后,程序就可以调用该对象的如下   四个个方法来访问Annotation信息:

  方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
  方法2:Annotation[] getAnnotations():返回该程序元素上存在的所有注解。
  方法3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
  方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。

程序举例:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface classIfo{
    String value() default "";
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface NameType{
    String value() default "这是乳名";
}
@Retention(RetentionPolicy.RUNTIME)
@interface adultIfo{
    String name() default "";
    int age() default 0;
}

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @
interface parentIfo{ int Marriage_time() default -1;
//这里是注解的嵌套,其实用起来跟一般的类型一样,使用的时候就把注解当成是接口就可以了 adultIfo [] parent()
default {}; } @classIfo("学生类-用来测试反射机制读取Annotation") class Student{
//不指定参数就是使用默认值 @NameType String name
="小明";
//这里注意数组和嵌套的使用 @parentIfo(Marriage_time
=20,parent={@adultIfo(name="baba",age=39),@adultIfo(name="mama",age=39)}) String getParent(){ return "parent"; } } public class Demo04 { public static void main(String[] args){ Class<?> cc=Student.class; Field[] ff=cc.getDeclaredFields(); for(Field f:ff){ if(f.isAnnotationPresent(NameType.class)){ NameType nt=f.getAnnotation(NameType.class); System.out.println("名字类型的说明 "+nt.value()); } } Method[] mm=cc.getDeclaredMethods(); for(Method m:mm){ if(m.isAnnotationPresent(parentIfo.class)){ parentIfo pi=m.getAnnotation(parentIfo.class); System.out.println("结婚时间:"+String.valueOf(pi.Marriage_time())); adultIfo ai[]=pi.parent(); System.out.println("父亲"+ai[0].name()+" "+ai[0].age()); System.out.println("母亲"+ai[1].name()+" "+ai[1].age()); } } } }

 


















以上是关于Java 注解的主要内容,如果未能解决你的问题,请参考以下文章

JAXB的@XmlElement注解

java代码在片段活动中不起作用

Android APT注解处理器 ( 根据注解生成 Java 代码 )

java 代码片段【JAVA】

# Java 常用代码片段

# Java 常用代码片段