java 注解
概述
注解是一系列元数据,它提供数据用来解释程序代码,而且注解对于代码的运行效果没有直接影响。
所谓的元数据是指用来描述数据的数据,更通俗一点就是描述代码间关系,或者代码与其它资源(例如数据库表)之间内在联系得数据
从例子入手认识注解
MyAnnotation.java
package com.demo.testmediastore;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
String name() default "unknown";
int old() default 100;
String[] toys() default {};
}
MyTest.java
package com.demo.testmediastore;
@MyAnnotation(name = "fzc",old = 7,toys = {"superman","vehicle"})
public class MyTest {
}
1、@interface
定义一个类的时候,会用上class + 类名,那当定义一个注解,是以@interface + 注解名,@interface MyAnnotation
2、@Retention(RetentionPolicy.RUNTIME)
@Retention 的作用,描述Annotation的作用作用域,通俗说,用来描述一个注解的生命范围
括号里的value:
RetentionPolicy.SOURCE:注解仅存在于源码中,在class字节码文件中不包含
RetentionPolicy.CLASS:默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
RetentionPolicy.RUNTIME: 注解会在class字节码文件中存在,在运行时可以通过反射获取到
3、@Target(ElementType.TYPE)
@Target 的作用,就是来指定 Annotation 的类型属性。通俗说,用来描述该注解使用在类中,变量,还是方法等里。
ElementType.TYPE:类、接口(包括注释类型)或枚举声明
ElementType.FIELD:字段声明(包括枚举常量)
ElementType.METHOD:方法声明
ElementType.PARAMETER:参数声明
ElementType.CONSTRUCTOR: 构造方法声明
ElementType.LOCAL_VARIABLE:局部变量声明
ElementType.ANNOTATION_TYPE:注释类型声明
ElementType.PACKAGE: 包声明
若没有 Target,则该Annotation可以用于以上任何地方
4、注解只有属性成员变量
声明形式为:
类型 + 变量名 + () + default + 默认值
例如上面的:
String name() default "unknown";
int old() default 100;
String[] toys() default {};
其中,注解属性可以为以下:
- 1.基本数据类型
- 2.String
- 3.枚举类型
- 4.注解类型
- 5.Class类型
- 6.以上类型的一维数组类型
5、注解成员变量赋值
如果注解又多个属性,则可以在注解括号中用“,”号隔开分别给对应的属性赋值
@MyAnnotation(name = "fzc",old = 7,toys = {"superman","vehicle"})
public class MyTest {
}
6、在反射中使用 Annotation
package com.demo.testmediastore;
public class Starter {
public static void main(String[] args) {
boolean hasAnnotation = MyTest.class.isAnnotationPresent(MyAnnotation.class);
if(hasAnnotation) {
MyAnnotation myAnnotation = MyTest.class.getAnnotation(MyAnnotation.class);
System.out.println(myAnnotation.name());
System.out.println(myAnnotation.old());
System.out.println(myAnnotation.toys());
}
}
}
7、常用的注解
@Deprecated – @Deprecated 所标注内容,不再被建议使用。
@Override – @Override 只能标注方法,表示该方法覆盖父类中的方法。
@Documented – @Documented 所标注内容,可以出现在javadoc中。
@Inherited – @Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。
@Retention – @Retention只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。
@Target – @Target只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。
@SuppressWarnings – @SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。
注解的用处
- 提供信息给编译器:编译器可以利用注解来探测错误和警告信息
- 编译阶段时的处理:软件工具可以利用注解信息来生成代码 html 文档或者其他相应的处理
- 运行时的处理:某些注解可以在程序运行的时候接受代码的提取
好处
- 提升开发效率
- 编译期间就可以验证正确性,差错很容易
- 保存在 class 文件中,降低维护成本
坏处
- 若要对配置项进行修改,需要修改 Java 文件,还需要重新打包编译
- 配置项编码在 Java 文件中,可扩展性差