一, 基本内置注解
name | 简介 |
---|---|
@Override | 表示这个方法重写了父类的方法 |
@Deprecated | 表示这个方法已经过期,不建议开发者使用 |
@SuppressWarnings | 这个注解的用处是忽略警告信息。 |
@SafeVarargs | jdk1.7后@SafeVarargs注解只能用在参数长度可变的方法或构造方法上,且方法必须声明为static或final,否则会出现编译错误 |
@FunctionalInterface | @FunctionalInterface这是Java1.8 新增的注解,用于约定函数式接口。 |
@SuppressWarnings
就对这些警告进行了抑制,即忽略掉这些警告信息。@SuppressWarnings 有常见的值,分别对应如下意思
1.deprecation:使用了不赞成使用的类或方法时的警告(使用@Deprecated使得编译器产生的警告);
2.unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型; 关闭编译器警告
3.fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
4.path:在类路径、源文件路径等中有不存在的路径时的警告;
5.serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告;
6.finally:任何 finally 子句不能正常完成时的警告;
7.rawtypes 泛型类型未指明
8.unused 引用定义了,但是没有被使用
9.all:关于以上所有情况的告。
二, 自定义注解
实现简单的仿spring的@Value注解, 实现变量,方法的赋值
@Value
实现作用于方法的参数和成员变量
@Value.java
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER })
public @interface Value {
String value() default "";
}
解析使用
JDBCConfig.java
public class JDBCConfig {
@Value("127.0.0.1")
private String host;
@Value("root")
private String passwd;
...
}
使用反射, 获取到成员变量, 在判断改变量是否添加了注解, 添加就赋值
Class<?> clazz = Class.forName("top.itkaoti.annotation.JDBCConfig");
JDBCConfig jdbcConfig = (JDBCConfig) clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
// 判断是否使用了value注解
if (field.isAnnotationPresent(Value.class)) {
Value annotation = field.getAnnotation(Value.class);
String value = annotation.value();
// 方法1:直接access为true
// if (!field.isAccessible()) {
// field.setAccessible(true);
// }
// field.set(jdbcConfig, value);
// 方法2: 调用set方法
String name = field.getName();
Method declaredMethod = clazz.getDeclaredMethod("set" + firstUpCase(name), value.getClass());
declaredMethod.invoke(jdbcConfig, value);
}
}
System.out.println(jdbcConfig);
三, 元注解
元注解有这么几种:
@Target
@Retention
@Inherited
@Documented
@Repeatable (java1.8 新增)
@Target
@Target 表示这个注解能放在什么位置上, @Value 这个注解上的@Target是:@Target({FIELD,PARAMETER}),表示可以用在变量和方法参数
类型 | 作用 |
---|---|
ElementType.TYPE | 能修饰类、接口或枚举类型 |
ElementType.FIELD | 能修饰成员变量 |
ElementType.METHOD | 能修饰方法 |
ElementType.PARAMETER | 能修饰参数 |
ElementType.CONSTRUCTOR | 能修饰构造器 |
ElementType.LOCAL_VARIABLE | 能修饰局部变量 |
ElementType.ANNOTATION_TYPE | 能修饰注解 |
ElementType.PACKAGE | 能修饰包 |
@Retention
@Retention 表示生命周期 @JDBCConfig 上的值是 RetentionPolicy.RUNTIME, 表示可以在运行的时候依然可以使用。
类型 | 作用 |
---|---|
RetentionPolicy.SOURCE | 注解只在源代码中存在,编译成class之后,就没了。@Override 就是这种注解。 |
RetentionPolicy.CLASS | 注解在java文件编程成.class文件后,依然存在,但是运行起来后就没了。@Retention的默认值,即当没有显式指定@Retention的时候,就会是这种类型。 |
RetentionPolicy.RUNTIME | 注解在运行起来之后依然存在,程序可以通过反射获取这些信息,自定义注解@Value 就是这样。 |
@Inherited
@Inherited 表示该注解具有继承性。如例,设计一个DBUtil的子类,其getConnection2方法,可以获取到父类DBUtil上的注解信息。
@Documented
@Documented 如图所示, 在用javadoc命令生成API文档后,DBUtil的文档里会出现该注解说明。
@Repeatable (java1.8 新增)
当没有@Repeatable修饰的时候,注解在同一个位置,只能出现一次,如例所示:
@Value("127.0.0.1")
@Value("root")
如果对同一个重复使用两次, 那么结果就会报错了。
使用@Repeatable之后,再配合一些其他动作,就可以在同一个地方使用多次了。
参考: