目录
元注释
负责注释其他注解,Java定义了4种标准元类型,用于描述其他类型
可以在java.lang中找到。
@:表示该注解是否包含在
@:表示子类可以继承父类的注解
@
最常用的元注释是@。 使用@来定义它可以在源代码中应用的位置:
例如,要定义注释@可以用在方法上,我们必须添加@(.)
@
另一个重要的元注释@定义了生命周期:
如果@不存在,则默认为CLASS。因为通常我们会自定义它,所以一定要添加@(.)元注释
@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@documented
@Inherited
@interface MyAnnotation {}
自定义注释
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.FIELD)
public @interface Range {
int min = 1;
int max = 7;
String msg = "长度不能小于" + Range.min + "或者大于" + Range.max;
String message() default msg;
int min() default min;
int max() default max;
}
使用注释
public class Person {
@Range
public String name;
@Range(min = 22, max = 50, message = "年龄不能小于22或者大于50")
public Integer age;
@Range(min = 3, max = 20, message = "长度不能小于3或者大于20")
public String city;
public Person() {}
public Person(String name, Integer age, String city) {
this.name = name;
this.age = age;
this.city = city;
}
// 此处省略 get/set ...
}
处理注解的方法
import java.lang.reflect.Field;
public class RangeCheck {
public static void check(Person person) throws IllegalAccessException, NullPointerException, IllegalArgumentException {
// 使用反射获取所有字段并遍历
for (Field field : person.getClass().getFields()) {
// 获取字段上的注解
Range range = field.getAnnotation(Range.class);
// 判断该字段是否使用了注解
if (range != null) {
// 获取字段的值, 这里可能会抛出 IllegalAccessException 访问权限异常
Object value = field.get(person);
System.out.println(field.getName() + " value--> " + value);
// 判断参数是否为空
if (value == null) {
throw new NullPointerException(field.getName() + "不能为空");
}
// String类型校验
else if (value instanceof String) {
// 如果是String类型就强转
String s = (String) value;
// 判断该值是否满足 @Range的min/max
if (s.length() < range.min() || s.length() > range.max()) {
throw new IllegalArgumentException("参数异常: " + field.getName() + range.message());
}
}
// Integer 类型校验
else if (value instanceof Integer) {
Integer i = (Integer) value;
if (i < range.min() || i > range.max()) {
throw new IllegalArgumentException("参数异常: " + field.getName() + range.message());
}
}
}
}
}
}
测试使用
class DemoApplicationTests {
public static void main(String[] args) {
Person person = new Person("Hello", 18, "深圳");
try {
RangeCheck.check(person);
}
// catch (IllegalAccessException e) {
// e.printStackTrace();
// }
// catch (IllegalArgumentException e) {
// e.printStackTrace();
// String message = e.getMessage();
// System.out.println("非法参数异常: --> " + message);
// }
// catch (NullPointerException e) {
// e.printStackTrace();
// String message = e.getMessage();
// System.out.println("空指针异常: --> " + message);
// }
catch (Exception e) {
e.printStackTrace();
if (e instanceof IllegalArgumentException) {
System.out.println("非法参数异常");
}
String message = e.getMessage();
System.out.println("所有异常: --> " + message);
}
}
}
java.lang.IllegalArgumentException: 参数异常: age年龄不能小于22或者大于50
at com.pro.pojo.RangeCheck.check(RangeCheck.java:35)
非法参数异常
所有异常: --> 参数异常: age年龄不能小于22或者大于50
2021-04-19 15:23:27.599 INFO 5604 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'