本文将学习注解开发、在实际案例中讲解注解使用和注解信息获取、了解几个Java常用内置注解
概述
Annotation(注解)是JDK1.5及以后版本引入的,以‘@注解名’在代码中存在。注解是一种独立于程序业务逻辑的标识,具有生成文档、跟踪代码依赖性、执行基本编译时检查代码格式等功能。
定义注解
注解的定义和Java类或接口既有相同点又有不同点,相同点在于定义格式是一样的,定义类使用关键词class,定义接口使用关键词interface,而定义注解使用关键词@interface;不同点在于设置内部属性各有不同,以及注解开发需要使用java的注解。
(位置:java.lang.annotation.*)
开发实例
新建一个java工程,仅开发注解时,仅需要JDK(1.5+),不需要引入第三方依赖;开发步骤和新建一个基础工程是一样的,不同的地方在于新建类的时候。
新建一个@interface类型的注解,加上Java注解和设置属性,如下代码所示:
1234567891011121314151617
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; @Documented@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface MyController { String name(); String value() default ""; String[] notes() default {"1", "2"};}
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;
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyController {
String name();
String value() default “”;
String[] notes() default {“1”, “2”};
}
Java注解:
@Documented 标记生成javadoc
@Retention 注解的生存期
@Target 注解的使用地方(修饰的对象范围)
(具体含义和参数设置见附1)
属性定义:
(1)属性定义采用 数据类型+属性名+小括号,最后分号的格式;如果该属性是必填项,则直接 数据类型+属性名+小括号(如String name()),如果该属性不是必填项,则可以使用关键词default(String name() default “”)设置默认值(为空或是其他);
(2)数据类型可以是所有基本数据类型(int,float,boolean,byte,double,char,long,short)、String类型、Class类型、Enum类型、Annotation类型以及数组。
(3)没有getter和setter属性。
(4)只能用public或默认(default)这两个访问权限修饰。
(5)若只有一个属性成员,建议把属性名称设为”value”,在使用的时候就可以省略属性名称,如:
1
@Annotation("属性值")
@Annotation(“属性值”)
多重注解
多重注解是JDK的一个新特性,有时候开发者需要在某个地方重复使用同一个注解,如果按照上述实例定义的注解则只能在同一个地方使用一次,因此,需要定义可供在同一个地方使用多次的注解。
首先,定义一个注解Parameter,如下代码所示:
123456789
@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Parameter { String name() default ""; String value() default "";}
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Parameter {
String name() default “”;
String value() default “”;
}
然后,定义一个注解Parameters,其属性数据类型为Parameter,如下代码所示:
1234567
@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Parameters { Parameter[] value();}
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Parameters {
Parameter[] value();
}
即Parameters包含多个Parameter,使用方式如下图所示:
使用时采用@Parameters({@Parameter})的格式。
也可以简化使用格式,在Parameter注解上加上@Repeatable()即可,使用@Repeatable()将@Parameters作为一个容器,如下图所示:
使用时则可简化使用方式,如下图所示:
使用注解
如果注解是单独工程,则需要引入该工程(和导入依赖是一样的)。
注解使用示例如图:
name和value为我们之前定义的注解属性。
注解获取实例
分别开发一个用于类上的注解MyController和一个用于类方法上的注解MyMethod,然后新建类UseAnnotation使用这个注解,然后通过代码获取到UseAnnotation中的注解信息。
MyController代码如下:
12345678910
@Documented@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface MyController { String name(); String value() default ""; }
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyController {
String name();
String value() default “”;
}
MyMethod代码如下:
12345678910
@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyMethod { String name(); String value() default ""; }
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyMethod {
String name();
String value() default “”;
}
UseAnnotation代码如下:
123456789101112131415
@MyController( name = "类名称:UseAnnotation", value = "类功能:自定义注解MyController使用示例")public class UseAnnotation { @MyMethod( name = "方法名称:UseMethod", value = "方法功能:自定义注解MyMethod使用示例" ) public void UseMethod() { // ... } }
@MyController(
name = “类名称:UseAnnotation”,
value = “类功能:自定义注解MyController使用示例”
)
public class UseAnnotation {
@MyMethod(
name = “方法名称:UseMethod”,
value = “方法功能:自定义注解MyMethod使用示例”
)
public void UseMethod() {
// …
}
}
获取步骤如下:
1、获取到UseAnnotation的Class对象
2、通过Class的getDeclaredAnnotation()方法获取到类上的MyController注解
3、输出MyController注解信息
4、通过Class的getDeclaredMethods()方法获取到UseAnnotation的方法
5、通过Method的getDeclaredAnnotation()方法获取到MyMethod注解
6、输出MyMethod注解信息
注:要获取到方法上的注解,需要先获取到该方法
演示代码如下:
12345678910111213141516171819
// 1、获取到UseAnnotation的Class对象Class? clazz = UseAnnotation.class;// 2、通过Class的getDeclaredAnnotation()方法获取到指定注解MyController myController = (MyController)clazz.getDeclaredAnnotation(MyController.class);if (myController != null) { // 3、输出MyController注解信息 System.out.println(myController.name() + ", " + myController.value());} // 4、通过Class的getDeclaredMethods()方法获取到UseAnnotation的方法Method[] method = clazz.getDeclaredMethods();for(Method me : method) { // 5、通过Method的getDeclaredAnnotation()方法获取到指定注解 MyMethod myMethod = (MyMethod)me.getDeclaredAnnotation(MyMethod.class); if (myMethod != null) { // 6、输出MyMethod注解信息 System.out.println(myMethod.name() + ", " + myMethod.value()); }}
// 1、获取到UseAnnotation的Class对象
Class? clazz = UseAnnotation.class;
// 2、通过Class的getDeclaredAnnotation()方法获取到指定注解
MyController myController = (MyController)clazz.getDeclaredAnnotation(MyController.class);
if (myController != null) {
// 3、输出MyController注解信息
System.out.println(myController.name() + “, “ + myController.value());
}
// 4、通过Class的getDeclaredMethods()方法获取到UseAnnotation的方法
Method[] method = clazz.getDeclaredMethods();
for(Method me : method) {
// 5、通过Method的getDeclaredAnnotation()方法获取到指定注解
MyMethod myMethod = (MyMethod)me.getDeclaredAnnotation(MyMethod.class);
if (myMethod != null) {
// 6、输出MyMethod注解信息
System.out.println(myMethod.name() + “, “ + myMethod.value());
}
}
运行结果:
注:(导包)
12345
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;
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;
Java内置注解
@Deprecated
该注解表明已被废弃不推荐使用,当某个方法(类、属性)出现一条删除线的时候,即表明该方法(类、属性)已被废弃不推荐使用了。
@Deprecated可以注解在类、方法和属性上标识废弃,通常某个方法(类、属性)进行了升级修改等情况的时候,由于原来的已经被广大用户所使用,因此不可能直接删除掉,所以采用此标识进行保留,但提示不再使用,这样既不会导致已使用的地方出现错误,又可以将新版本推出。
@Override
该注解表明该方法是继承自父类的方法,如果是必须要继承自父类的方法,建议进行@Override注解,因为如果开发者修改了方法的原有架构导致和父类的方法不一致时,使用@Override将会进行检查报错,以达到提醒开发者的目的。
@SuppressWarnings
用于抑制编译器产生警告信息,如果开发者使用了不推荐的方法、不安全的类型转换的时候,编辑器会给出警示信息(如黄色的感叹号),有时候警告信息会影响我们的开发工作,比如挡住了断点使得无法判断是否进行断点设置。使用@SuppressWarnings注解可以帮助去掉警示信息。
附1
@Retention:注解的生命周期
@Target:注解使用地方
— END —
原文始发于微信公众号(程序员阿木):【Java】注解开发