Java注解
Java注解
注解,类似于注释,不过不同于注释,注释是给程序员(媛)看的,而注解则是给计算机看的,用于在需要做特定处理的位置做标记,并可以传入一些参数来做更复杂的进一步操作,注解可以位于类、成员变量、方法等上方。
注解的基本结构
@Documented //元注解,用于对注解做进一步说明
@Retention(RetentionPolicy.RUNTIME) //元注解,用于对注解做进一步说明
@Target(ElementType.ANNOTATION_TYPE)//元注解,用于对注解做进一步说明
public @interface Target {
//不同于一般的类和接口,该处的声明分别代表参数类型和参数名
//传参方式:单值:value=ElementType.METHOD,多值:value={ElementType.CONSTRUCTOR, ElementType.FIELD})
ElementType[] value();
}
需要注意的地方
- 在定义了参数后,使用注解时就必须给参数赋值,可以在参数后通过增加default指定默认值的方式来避免不必要的手动赋值
- 当注解中只有一个参数时,并且参数名为value时,value可以省略不写
- 数组赋值时,使用{}包裹,如果数组中只有一个值,则{}可以省略
- 参数类型可以有的几种取值:基本数据类型、String、枚举、注解以及对应类型的数组
元注解
元注解用于对注解作出进一步解释的注解,常用的有@Target、@Retention、@Documented、@Inherited等,下面对注解进行介绍
@Target
@Target注解用于描述注解的使用范围,常用的有以下值:
ElementType.TYPE //类,接口,枚举等
ElementType.FIELD //成员变量
ElementType.METHOD //方法
@Retention
@retention注解用于设置注解的保留策略,有以下三种取值:
RetentionPolicy.SOURCE //该类型的注解在编译时会被丢弃,即只保存在源码中
RetentionPolicy.CLASS //该类型的注解会被编译器保留到字节码文件中,但不会在运行时被JVM保留,该配置是默认的策略
RetentionPolicy.RUNTIME //该类型的注解不仅会被编译器保留包字节码文件中,还会在JVM运行时保留,所以该类型的注解可以通过反射读取,一般自定义注解使用方式
@Documented
@documented注释的部分,在使用javac生成API文档时会成为API的一部分
//上述基本结构举例的@Target注解上就有元注解@Documented,在API文档中查看@Target的部分就会把注解部分也加入其中,如下所示
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Target
@Inherited
@Inherited注解标记的注解,只有在类上才有效(只有类有继承关系),被该注解标记的类,其子类会自动继承父类的所有注解,以下使用自定义注解来演示该注解的使用:
//注解的定义
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}) //可以在类,成员变量,方法上使用
@Retention(RetentionPolicy.RUNTIME) //保留策略为RUNTIME,可以在JVM中运行时被加载
@Inherited
public @interface Mango {
String value(); //不带默认值的value参数,使用时必须手动赋值
String[] attr() default {"默认值1", "默认值2"};//带默认值参数attr,使用时可以不必手动赋值
}
//父类定义
@Mango("value属性值")
public class Father {
}
//子类的定义
public class Children extends Father{
public static void main(String[] args) {
Mango annotation = Children.class.getAnnotation(Mango.class);
System.out.println(annotation.attr()[1]);
System.out.println(annotation.value());
}
}
//对应的运行结果值
默认值2
value属性值
常见的内置注解
@Override
@Override是一个空接口,用于标记,最后会用一个案例来阐明标记的意义
@Override重写父类的方法,被该注解修饰的方法如果没有重写父类的方法,编译器会报异常
@Deprecated
@Deprecated也是一个空接口,用于遗弃该方法,被该注解修饰的方法通常是因为它很危险或存在更好的选择,而且可能在未来会被删除,一般不鼓励程序员再去使用该方法,当然,如果方法依旧存在,也是可以调用的,不过会提出警告,如果不想理会警告,可以使用@SuppressWarnings("deprecation")来镇压警告信息
@SuppressWarnings
@SuppressWarnings接口用于抑制编译时的警告信息,有如下参数可以使用
deprecation:使用了过时的类或方法的警告
unchecked:执行了未检查的转换时的警告,如使用集合是未指定泛型
fallthrough:当在switch语句使用时发生case穿透
path:在类路径、源文件路径等中有不存在路径的警告
serial:当在可序列化的类上缺少serialVersionUID定义时的警告
finally:任何finally子句不能完成时的警告
unuse:变量定义后未被使用
resource:资源对象未释放
all:关于以上所有情况的警告
放在最后,一个很有用的注解使用案例
注解的定义
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Transactional {
}
主代码
public class TestServiceImpl {
@Transactional
public String getSomeMsg() {
/* some code */
System.out.println("some operation");
return "result";
}
public static void main(String[] args) throws Exception {
Class<TestServiceImpl> Service = (Class<TestServiceImpl>) Class.forName("com.mango.test.TestServiceImpl");
TestServiceImpl testServiceImpl = Service.newInstance();
for (Method method : Service.getMethods()) {
if (method.isAnnotationPresent(Transactional.class)) {
System.out.println("事务开启");
method.invoke(testServiceImpl);
System.out.println("事务提交");
}
}
}
}
运行结果
事务开启
some operation
事务提交
如果对你有帮助,点个赞,或者打个赏吧,嘿嘿
整理不易,请尊重博主的劳动成果