JAVA 枚举校验注解 允许null java实例
时间: 2023-08-24 09:29:33 浏览: 116
如果需要在 Java 中使用注解来实现枚举校验,可以利用注解处理器来实现。具体来说,我们可以定义一个注解 EnumValue,该注解用于标记需要进行枚举校验的字段或方法参数。然后,我们可以编写一个注解处理器 EnumValueProcessor,该处理器会在编译时扫描代码中的 EnumValue 注解,并生成对应的校验代码。示例代码如下:
```java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumValue {
Class<? extends Enum<?>> value();
}
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.MirroredTypeException;
import javax.tools.Diagnostic;
import java.util.Set;
public class EnumValueProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element element : roundEnv.getElementsAnnotatedWith(EnumValue.class)) {
if (element.getKind() == ElementKind.FIELD) {
processField(element);
} else if (element.getKind() == ElementKind.PARAMETER) {
processParameter(element);
}
}
return true;
}
private void processField(Element element) {
try {
Class<? extends Enum<?>> enumClass = element.getAnnotation(EnumValue.class).value();
String fieldName = element.getSimpleName().toString();
String enumName = enumClass.getSimpleName();
String code = String.format("if (%s != null && !%s.class.isEnumConstant(%s)) {throw new IllegalArgumentException(\"%s must be one of %s values\");}",
fieldName, enumName, fieldName, fieldName, enumName);
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generated code: " + code, element);
} catch (MirroredTypeException ex) {
// Do nothing
}
}
private void processParameter(Element element) {
try {
Class<? extends Enum<?>> enumClass = element.getAnnotation(EnumValue.class).value();
String paramName = element.getSimpleName().toString();
String enumName = enumClass.getSimpleName();
String code = String.format("if (%s != null && !%s.class.isEnumConstant(%s)) {throw new IllegalArgumentException(\"%s must be one of %s values\");}",
paramName, enumName, paramName, paramName, enumName);
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generated code: " + code, element);
} catch (MirroredTypeException ex) {
// Do nothing
}
}
}
public enum Fruit {
APPLE,
BANANA,
ORANGE
}
public class EnumValidationDemo {
@EnumValue(Fruit.class)
private String fruit;
public void setFruit(@EnumValue(Fruit.class) String fruit) {
this.fruit = fruit;
}
public static void main(String[] args) {
EnumValidationDemo demo = new EnumValidationDemo();
demo.setFruit("APPLE");
}
}
```
在上面的代码中,我们首先定义了一个注解 EnumValue,该注解用于标记需要进行枚举校验的字段或方法参数。然后,我们编写了一个注解处理器 EnumValueProcessor,该处理器会在编译时扫描代码中的 EnumValue 注解,并根据注解所标记的字段或方法参数生成对应的校验代码。在 processField() 和 processParameter() 方法中,我们使用 Element.getAnnotation() 方法获取注解的信息,并利用 String.format() 方法生成对应的校验代码。生成的代码会通过 Messager.printMessage() 方法输出到控制台。最后,在 EnumValidationDemo 类中,我们使用 @EnumValue(Fruit.class) 注解来标记 fruit 字段和 setFruit() 方法的参数,表示需要进行 Fruit 枚举校验。运行程序后,可以看到生成的校验代码为:
```java
if (fruit != null && !Fruit.class.isEnumConstant(fruit)) {throw new IllegalArgumentException("fruit must be one of Fruit values");}
```
这段代码会在 setFruit() 方法中被调用,用于校验输入值是否为 Fruit 枚举类型。
阅读全文