Java 中的注解
Java 注解(Annotation) 是JDK1.5引入的。同时也定义一套注解,共有7个。
- 注解的作用:它不是程序本身,却可以对程序作出解释;可以被其他程序读取并解析。
- 注解的格式:
单个参数:@Retention(RetentionPolicy.RUNTIME) @Retention(value=RetentionPolicy.RUNTIME)
多个参数:@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
代码中的注解
- @Override :重写标记,在子类继承父类后,标记在重写后过后的子类方法上,如果发现父类,或者是引用的接口中没有该方法时,编译报错。
- @Deprecated:标记过时的代码,不推荐使用的方法。
- @SuppressWarnings:忽略编译器警告
元注解
元注解就是用来标记注解的注解。
- @Retention:标记如何存储,三个参数
1:RetentionPolicy.SOURCE 注释只保留在源文件中,当Java文件编译成class文件时,被标记注解会被遗弃。
2:RetentionPolicy.CLASS 注解被保留在class文件,但jvm加载class文件时被遗弃,默认的生命周期。
3:RetentionPolicy.RUNTIME 注解不仅被保留在class文件中,jvm加载class文件之后,仍然存在。
可以查看一下java源码中的英文注释
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 :标记这些注解是否包含在JavaDoc中。
/**
* Indicates that annotations with a type are to be documented by javadoc
* and similar tools by default. This type should be used to annotate the
* declarations of types whose annotations affect the use of annotated
* elements by their clients. If a type declaration is annotated with
* Documented, its annotations become part of the public API
* of the annotated elements.
*
* @author Joshua Bloch
* @since 1.5
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
- @Target :该注解说明了被标记注解的修饰范围。package、type(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量等。
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
- @Inherited :标记这个注解是继承与那个注解类的。
JDK1.7中的注解
- @SafeVarargs :在声明可变参数的构造方法或方法时,java编译器会报unchecked警告,使用该注解忽略这个警告。
- @FunctionalInterface :表示一个函数式接口
- @Repeatable :标识某个注解可以同一个声明多次
自定义注解
一定一个带一个参数的注解
/**
* 自定义注解 单个参数
* @author lingyiwin
*/
@Retention(value = RetentionPolicy.SOURCE)
@Target(value = {ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotationMethod {
String value();
}
定义一个多个参数的注解
参数可以设置默认值。
/**
* 自定义注解 多个参数
* @author lingyiwin
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
public @interface MyAnnotationMorAargument {
int id() default -1;
int age() default 18;
String stuName() default "";
String[] school() default {"清华","北大"};
}
注解的解析
定义完注解,代码中也使用了该注解,如果没有解析的程序,该注解是没有作用的。
注意:如果自定义注解中 @Retention(value = RetentionPolicy.RUNTIME) 不是RUNTIME 解析时获取不到的。
/**
* 定义注解 MyAnnotationTable
* 解析时,获取value中的表名
* @author lingyiwin
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotationTable {
String value();
}
/**
* 定义注解MyAnnotationField
* 标记Field属性 对应数据库中 列名、类型、长度
* @author lingyiwin
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.FIELD)
public @interface MyAnnotationField {
String columnName();
String type();
int length();
}
/**
* @author lingyiwin
* 使用反射解析定义的注解信息,通过获取的信息做一些操作
*/
public class ResolveAnnotation {
public static void main(String[] args) {
try {
Class clazz = Class.forName("com.lingyiwin.annotation.Person");
Annotation[] annotations = clazz.getAnnotations();
for (Annotation an :annotations) {
System.out.println(an);
}
MyAnnotationTable myAnnotationTable = (MyAnnotationTable) clazz.getAnnotation(MyAnnotationTable.class);
String value = myAnnotationTable.value();
System.out.println(value);
Field[] fields = clazz.getDeclaredFields();
for (Field field :fields) {
MyAnnotationField annotationField = field.getAnnotation(MyAnnotationField.class);
System.out.println(annotationField.columnName()+":"+annotationField.type()+":"+annotationField.length());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
查阅资料,总结,写笔记。如果能帮助到你,希望点个收藏和关注。谢谢。