【Java】如何自定义注解

一、问题
在实体类中,如何通过注解校验必输字段,字段长度,是否必输等过滤条件?

二、分析

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 +默认值

的方式来定义方法;

你可能感兴趣的:(【基础】,【JavaEE】)