欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java注解之基本语法

程序员文章站 2024-02-16 09:44:04
...

不管是做后端开发还是前端开发,在实际开发中都会涉及到注解这个知识点。今天主要针对Java的注解进行讲解,考虑到篇幅问题,这篇主要分享Java注解的基本语法,以及几个简单的示例。

为什么要学习注解呢?

现在不管是后端工程师还是前端工程师,都会使用到各种各样的框架,在每一个框架里面,都会大量使用到注解,为了能够读懂框架源码,我们必须会使用注解;使用注解也可以使我们的代码变得简洁。

第一部分:JDK自带注解

在JDK中有大量的注解,下面通过一个简单的示例说明。

1. 创建一个Offer接口,定义两个方法,如下:

package com.study.annotation.default_annotation;

/**
 * <p>Title: Offer</p >
 * <p>Description: offer interface </p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/10/10 21:58
 * @Version: 1.0
 */
public interface Offer {

    String findName();

    @Deprecated
    String obtainIdfa();
}

在上面我们使用了第一个注解@Deprecated,这个注解使用在此处的原因是obtainIdfa()方法已经遗弃,但是为了不影响已经使用了该方法的类,所以将该方法添加注解说明。

该注解的定义如下:


package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * A program element annotated &#64;Deprecated is one that programmers
 * are discouraged from using, typically because it is dangerous,
 * or because a better alternative exists.  Compilers warn when a
 * deprecated program element is used or overridden in non-deprecated code.
 *
 * @author  Neal Gafter
 * @since 1.5
 * @jls 9.6.3.6 @Deprecated
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

现在这段代码可能看不懂,但是不要着急,等看完后面的知识点,回过头来再看这段代码,大家会觉得特别简单。

2. 实现Offer接口,代码如下:


package com.study.annotation.default_annotation;

/**
 * <p>Title: OfferImp</p >
 * <p>Description: offer接口实现</p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/10/10 21:59
 * @Version: 1.0
 */
public class OfferImp implements Offer {

    @Override
    public String findName() {
        return null;
    }

    @Override
    public String obtainIdfa() {
        return null;
    }
}

上面使用到了@Override注解,相信Java开发人员对这个注解不会陌生,该注解表明方法是一个覆盖方法。该注解定义如下:


package java.lang;

import java.lang.annotation.*;

/**
 * Indicates that a method declaration is intended to override a
 * method declaration in a supertype. If a method is annotated with
 * this annotation type compilers are required to generate an error
 * message unless at least one of the following conditions hold:
 *
 * <ul><li>
 * The method does override or implement a method declared in a
 * supertype.
 * </li><li>
 * The method has a signature that is override-equivalent to that of
 * any public method declared in {@linkplain Object}.
 * </li></ul>
 *
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 9.6.1.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

当然,在学习完这节内容我们再看该注解的定义。

我们在Offer接口定义中,对obtainIdfa()使用了@Deprecated注解,那么怎么模拟查看该注解的实际效果了,我们看下面代码(该段代码要截图展示,不然看不出实际效果):

Java注解之基本语法

我们看到在实际使用obtainIdfa()方法的时候,该方法会有横线划掉的标志。那么我们怎么不让编译器检查到这个警告了?这里我们又要使用到JDK提供给我们的一个注解,如下:

 

Java注解之基本语法

可以看到obtainIdfa()方法的警告没有了。

第二部分:注解基本语法

1.  注解分类

注解分为编译时注解、运行时注解、源码注解

编译时注解:注解在源码和.class文件中都存在(上面使用到的几个注解都属于编译时注解);

运行时注解:在运行时也会起作用,运行时注解可以影响到程序的实际逻辑;

源码注解:只在源码中存在,代码编译成.class文件之后,注解就不存在了。

注意:除过上面提到的三类注解之外,还有一个元注解,元注解使给注解进行注解。

2. 自定义注解

我们先看一个已有注解的定义语法,通过分析具体语法,定义出自己的注解,代码如下:

Java注解之基本语法

1.  注解定义关键字

@interface关键字表明,定义的既不是类也不是接口,而是一个注解,所以定义注解第一步就是使用@interface

2. 注解成员

在上面注解定义的成员为:


String value() default "";

成员定义:成员没有参数、没有异常进行定义;可以使用default给成员赋默认值;

成员类型:成员类型使受限制的,注解合法的成员类型为原始类型、String、Class、Annotation、Enumeration;

约定:如果注解只有一个成员,我们约定该成员命名为value,在使用的时候,可以省略成员名和赋值号(=)。

注意:注解可以没有成员,没有成员的注解我们称为标识注解。

3. 元注解

在上面注解里面的元注解为:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented

(1)@Target({ElementType.METHOD, ElementType.TYPE})元注解定义注解的作用域,注解作用域我们查看源码可以看到有如下几类:


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
}

每一个作用域都有注释,这里就不多做介绍。

(2)@Retention(RetentionPolicy.RUNTIME)元注解定义注解的生命周期,通过查看源码我们可以看到声明周期有如下几类:

package java.lang.annotation;

/**
 * Annotation retention policy.  The constants of this enumerated type
 * describe the various policies for retaining annotations.  They are used
 * in conjunction with the {@link Retention} meta-annotation type to specify
 * how long annotations are to be retained.
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * 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
     */
    RUNTIME
}

每一个生命周期定义都有详细的注释说明,这里不多赘述。

(3) @Inherited是一个标志性的元注解,它表明允许子类继承;

(4) @Documented表明生成Java的doc文档时会包含注解的信息。

第三部分:自定义注解

根据上面的语法,我们自定义一个注解,并且实际使用它,代码如下:


package com.study.annotation.user_defined;


import java.lang.annotation.*;

/**
 * <p>Title: Util</p >
 * <p>Description: 自定义注解</p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/10/10 23:30
 * @Version: 1.0
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Util {
    String desc();

    String auth() default "WEIQI";

    String dateTime();
}

这里定一个工具类描述性注解,成员包括描述、作者、时间信息。

第四部分:使用自定义注解

我们使用上面自定义注解,代码如下:


package com.study.annotation.user_defined;

import org.springframework.stereotype.Component;

/**
 * <p>Title: CommonParameter</p >
 * <p>Description: common parameter</p >
 * <p>Company: http://www.yinjiedu.com</p >
 * <p>Project: concurrency</p >
 *
 * @author: qiwei
 * @Date: 2019/10/10 23:36
 * @Version: 1.0
 */
@Component
@Util(desc = "公共参数定义", dateTime = "2019-10-10")
public class CommonParameter {
    public final static String SUCCESS_CODE = "200";
}

通过上述例子可以看到,注解使用了default关键字定义了默认值之后,在使用注解的时候可以不用显示的处理。

关于注解的基本语法就介绍这么多,相信大家读到这里,对JDK自带注解的阅读都没有一点问题。有关注解的高级用法,会再出一篇文章来分享。

 

思考:注解的高级用法怎么使用,主要用在哪里?

提示:注解的高级用法要结合Java的反射机制来做,在平时工作中使用到的第三方注解,都使用到这方面的只是,大家可以自己实现一个简单的例子试试。

了解实时文章信息,请关注微信公众号《编程之艺术》

Java注解之基本语法