一、问题
在实体类中,如何通过注解校验必输字段,字段长度,是否必输等过滤条件?
二、分析
1.自定义注解(annotation)
像@Autowired自动织入注解等,都是通过注解,让编译器在编译过程中,自动做一些解析操作,我们可以通过这一机制,让编译器自动为我们做一些动作;首先,我们来看一些如何自定义注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
@Retention(RetentionPolicy.RUNTIME)
/** Field declaration (includes enum constants) */
@Target({ElementType.FIELD})
public @interface DemoAnnotation {
//字段长度
int length() default 0;
//是否必输
boolean isNotNull() default true;
//文件名称
String fieldName() default "";
}
这个类,是一个最基本的注解类,解析如下:
1、实体类是通过class来定义的,接口是用过interface来定义的,而注解是通过@interface来定义的;你可以把标枪当成一种特殊的接口;
2、@Retention表示了作用时间,滞留周期,通过官方的注解,我们可以知道:class文件中的注解会被编译器记录,并且当虚拟机运行时一直被保存(言下之意即知道虚拟机结束运行),它会通过反射的方式读取;
@Retention(RetentionPolicy.RUNTIME)
3、@Target({ElementType.FIELD})表名了作用范围,这里我们如果做字段的校验,选枚举类中的FIELD即可;除此之外,我们还可以选ElementType 中枚举的其他类型:
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.lang.annotation;
/**
* The constants of this enumerated type provide a simple classification of the
* syntactic locations where annotations may appear in a Java program. These
* constants are used in {@link Target java.lang.annotation.Target}
* meta-annotations to specify where it is legal to write annotations of a
* given type.
*
* The syntactic locations where annotations may appear are split into
* declaration contexts , where annotations apply to declarations, and
* type contexts , where annotations apply to types used in
* declarations and expressions.
*
*
The constants {@link #ANNOTATION_TYPE} , {@link #CONSTRUCTOR} , {@link
* #FIELD} , {@link #LOCAL_VARIABLE} , {@link #METHOD} , {@link #PACKAGE} ,
* {@link #PARAMETER} , {@link #TYPE} , and {@link #TYPE_PARAMETER} correspond
* to the declaration contexts in JLS 9.6.4.1.
*
*
For example, an annotation whose type is meta-annotated with
* {@code @Target(ElementType.FIELD)} may only be written as a modifier for a
* field declaration.
*
*
The constant {@link #TYPE_USE} corresponds to the 15 type contexts in JLS
* 4.11, as well as to two declaration contexts: type declarations (including
* annotation type declarations) and type parameter declarations.
*
*
For example, an annotation whose type is meta-annotated with
* {@code @Target(ElementType.TYPE_USE)} may be written on the type of a field
* (or within the type of the field, if it is a nested, parameterized, or array
* type), and may also appear as a modifier for, say, a class declaration.
*
*
The {@code TYPE_USE} constant includes type declarations and type
* parameter declarations as a convenience for designers of type checkers which
* give semantics to annotation types. For example, if the annotation type
* {@code NonNull} is meta-annotated with
* {@code @Target(ElementType.TYPE_USE)}, then {@code @NonNull}
* {@code class C {...}} could be treated by a type checker as indicating that
* all variables of class {@code C} are non-null, while still allowing
* variables of other classes to be non-null or not non-null based on whether
* {@code @NonNull} appears at the variable's declaration.
*
* @author Joshua Bloch
* @since 1.5
* @jls 9.6.4.1 @Target
* @jls 4.1 The Kinds of Types and Values
*/
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
3、注解中的成员变量只允许public和abstract修饰,因为注解的特性就是通用的,公共的,所以不允许private等这类的小范围的标签;
4、定义成员变量使用
类型+方法名+()+defvalue +默认值
的方式来定义方法;