深入浅出 Java 注解!

简介: 深入浅出 Java 注解!

注解简介

所谓注解,其实就像一种拥有特定作用的注释,自 JDK1.5 及之后版本所引入的特性,它是放在 Java 源码的类、方法、字段、参数前的一种用作标注的“元数据”,与类、接口、枚举处于同一个层次中。


通过其作用的不同,我们常常将注解分为如下 3 类:


编写文档:通过代码中标识的注解生成对应文档(即类似于 Java doc 的文档);

代码分析:通过代码中标识的注解对代码进行分析(使用反射);

编译检查:通过代码中标识的注解让编译器能实现基本的编译检查(@Override);

常用的预定义注解

@Override

一般是用在方法上,表示重写该父类的方法,比如我们使用最多的 toString() 方法,它是 Object 类的一个方法,而我们的写的类都是继承自 Object 类,所以我们自定义的所有类都是有 toString() 方法的。但是如果我们自定义类中的方法在父类中没有,则不能使用该注解,否则会导致无法编译通过。


package com.cunyu;
/**
 * Created with IntelliJ IDEA.
 *
 * @author : cunyu
 * @version : 1.0
 * @email : 747731461@qq.com
 * @website : https://cunyu1943.github.io
 * @date : 2021/6/20 10:04
 * @project : JavaWeb
 * @package : com.cunyu
 * @className : OverrideTest
 * @description :
 */
public class OverrideTest {
    private Integer id;
    private String name;
    public OverrideTest(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("OverrideTest{");
        sb.append("id=").append(id);
        sb.append(", name='").append(name).append('\'');
        sb.append('}');
        return sb.toString();
    }
    public static void main(String[] args) {
        Integer id = 101;
        String name = "村雨遥";
        OverrideTest overrideTest = new OverrideTest(id, name);
        System.out.println(overrideTest);
    }
}

image.png

@Deprecated

一般用在方法之前,表示该方法已经过期,不建议再继续使用(但是仍然有效,只不过可能有更新的版本,推荐使用更新的版本)。

package com.cunyu;
/**
 * Created with IntelliJ IDEA.
 *
 * @author : cunyu
 * @version : 1.0
 * @email : 747731461@qq.com
 * @website : https://cunyu1943.github.io
 * @公众号 : 村雨遥
 * @date : 2021/6/20 10:07
 * @project : JavaWeb
 * @package : com.cunyu
 * @className : DeprecateTest
 * @description :
 */
public class DeprecateTest {
    @Deprecated
    public static void sayHello() {
        System.out.println("Hello World!");
    }
    public static void newSayHello() {
        System.out.println("Hello,Welcome to Java !");
    }
    public static void main(String[] args) {
        sayHello();
        newSayHello();
    }
}

image.png@SuppressWarnings

表示忽略警告信息,常用的值以及含义如下表:


值 描述

deprecation 使用了不赞成使用的类或方法时的警告

unchecked 使用了未经检查的转换时的警告

fallthrough 当 switch 程序块直接通往下一种情况而没有 break 时的警告

path 在类路径、源文件路径等中有不存在的路径时的警告

serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告

finally 任何 finally 子句不能正常完成时的警告

rawtypes 泛型类型未指明

unused 引用定义了,但是没有被使用

all 关闭以上所有情况的警告


package com.cunyu;
import java.util.ArrayList;
import java.util.List;
/**
 * Created with IntelliJ IDEA.
 *
 * @author : cunyu
 * @version : 1.0
 * @email : 747731461@qq.com
 * @website : https://cunyu1943.github.io
 * @公众号 : 村雨遥
 * @date : 2021/6/20 10:07
 * @project : JavaWeb
 * @package : com.cunyu
 * @className : SuppressWarningsTest
 * @description :
 */
public class SuppressWarningsTest {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        String item = "村雨遥";
        @SuppressWarnings("rawtypes")
        List items = new ArrayList();
        items.add(item);
        System.out.println(items);
    }
}

image.png自定义注解

格式

我们可以使用 @interface 来自定义注解,其格式如下:


public @interface AnnotationName{

   // 属性列表

   ……

}


一个简单的示例如下,其中 AnnoDemo 代表着我们自定义注解的名称,而 name()、age()、score() 则分别表示自定义注解的三个属性,而且我们利用关键字 default 对每个属性都赋予了默认值。


public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


原理

注解本质上相当于一个接口,它默认继承自 java.lang.annotation.Annotation。


public interface AnnotationName extends java.lang.annotation.Annotation{}


参数

注解的参数类似于无参的方法,通常我们推荐用 default 来设定一个默认值,对于方法的基本要求通常有如下几点:


方法的返回值类型不可以是 void;

如果定义了方法,那么在使用时需要给方法进行赋值,赋值的规则如下:

若定义方法时,使用了关键字 default 对方法赋予了默认初始值,那么在使用注解时,可以不用对方法进行再次赋值;

若只有一个方法需要赋值,且方法名为 value,那么此时 value 可以省略,直接定义值即可;

数组赋值时,值需要用大括号 {} 包裹,若数组中只有一个值,那么此时 {} 可以省略;

public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


如上述例子中,name()、age()、score() 就是我们自定义注解的参数。而当我们要是用该注解时,则通过如下方式来对参数进行赋值。


@AnnoDemo(name = "村雨遥", age = 26, score = 95.0f)

public class Demo{

   ……

}


元注解

定义

所谓元注解(meta annotation),就是可以用来修饰其他注解的注解。


常用的元注解

@Target

描述注解所修饰的对象范围,其取值主要有如下几种:


值 说明

ElementType.TYPE 表示可以作用于类或接口

ElementType.FIELD 表示可以作用于成员变量

ElementType.METHOD 表示可以作用于方法

ElementType.CONSTRUCTOR 表示可以作用于构造方法

ElementType.PARAMETER 表示可以作用于方法的参数

@Target(ElementType.TYPE)

public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


@Retention

用于约束注解的生命周期,其取值如下:


值 说明

RetentionPolicy.SOURCE 表示在源代码文件中有效,注解将被编译器丢弃(注解信息仅保留在源码中,源码经编译后注解信息丢失,不再保留到字节码文件中)

RetentionPolicy.CLASS 表示在字节码文件中有效,注解在字节码文件中可用,但会被 JVM 丢弃

RetentionPolicy.RUNTIME 表示在运行时有效,此时可以通过反射机制来读取注解的信息

@Target(ElementType.TYPE)

@Retention(RetentionPoicy.RUNTIME)

public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


@Documented

描述其他类型的注解是否被抽取到 API 文档中。


@Target(ElementType.TYPE)

@Retention(RetentionPoicy.RUNTIME)

@Documented

public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


@Inherited

这是一个标记注解,描述某个注解能够被子类继承,但是该元注解只适合已经配置了 @Target(ElementType.TYPE) 类型的自定义注解,而且仅针对于类的继承,而对于接口的继承则无效。


@Inherited

public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


@Repeatable

该注解是从 JDK1.8 新引入的元注解,表示在同一位置能够重复相同的注解。在没有该注解之前,我们一般是无法在同一类型上使用相同注解的,但引入该注解后,我们就可以在同一类型上使用相同注解。


@Target(ElementType.TYPE)

@Repeatable(AnnoDemos.class)

public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


public @interface AnnoDemos{

AnnoDemo[] value();

}


利用 @Repeatable 配置自定义注解之后,我们就可以在某个类型声明处添加多个我们自定义的注解了。


@AnnoDemo(name = "村雨遥", age = 26, score = 88.0f)

@AnnoDemo(name = "晓瑜", age = 27, score = 90.0f)

public class Student{

   ……

}


总结

总结上述的知识点,我们将自定义注解的过程归纳为如下 3 步。


定义一个注解

public @interface AnnoDemo{

}


添加参数并设置默认值

public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


利用元注解来配置我们的自定义注解

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface AnnoDemo{

   String name() default "村雨遥";

   int age() default 20;

   float score() default 60.0f;

}


在实际应用过程中,利用元注解配置自定义注解时,必须设置 @Target 和 @Retention 两个元注解,而且 @Retention 的值通常是设置为 RetentionPolicy.RUNTIME。


好了,以上就是我们注解的相关概念以及自定义注解所需要的掌握的一些知识点了,如果你觉得对你有所帮助,那就来一波点赞关注吧!


目录
相关文章
|
28天前
|
XML Java 编译器
Java学习十六—掌握注解:让编程更简单
Java 注解(Annotation)是一种特殊的语法结构,可以在代码中嵌入元数据。它们不直接影响代码的运行,但可以通过工具和框架提供额外的信息,帮助在编译、部署或运行时进行处理。
86 43
Java学习十六—掌握注解:让编程更简单
|
22天前
|
Java 开发者 Spring
[Java]自定义注解
本文介绍了Java中的四个元注解(@Target、@Retention、@Documented、@Inherited)及其使用方法,并详细讲解了自定义注解的定义和使用细节。文章还提到了Spring框架中的@AliasFor注解,通过示例帮助读者更好地理解和应用这些注解。文中强调了注解的生命周期、继承性和文档化特性,适合初学者和进阶开发者参考。
43 14
|
22天前
|
前端开发 Java
[Java]讲解@CallerSensitive注解
本文介绍了 `@CallerSensitive` 注解及其作用,通过 `Reflection.getCallerClass()` 方法返回调用方的 Class 对象。文章还详细解释了如何通过配置 VM Options 使自定义类被启动类加载器加载,以识别该注解。涉及的 VM Options 包括 `-Xbootclasspath`、`-Xbootclasspath/a` 和 `-Xbootclasspath/p`。最后,推荐了几篇关于 ClassLoader 的详细文章,供读者进一步学习。
29 12
|
16天前
|
Java 编译器
Java进阶之标准注解
Java进阶之标准注解
28 0
|
1月前
|
JSON Java 数据库
java 常用注解大全、注解笔记
关于Java常用注解的大全和笔记,涵盖了实体类、JSON处理、HTTP请求映射等多个方面的注解使用。
35 0
java 常用注解大全、注解笔记
|
2月前
|
Arthas Java 测试技术
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
Java字节码文件、组成、详解、分析;常用工具,jclasslib插件、阿里arthas工具;如何定位线上问题;Java注解
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
|
1月前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
16 0
|
2月前
|
Java 编译器 程序员
Java注解,元注解,自定义注解的使用
本文讲解了Java中注解的概念和作用,包括基本注解的用法(@Override, @Deprecated, @SuppressWarnings, @SafeVarargs, @FunctionalInterface),Java提供的元注解(@Retention, @Target, @Documented, @Inherited),以及如何自定义注解并通过反射获取注解信息。
Java注解,元注解,自定义注解的使用
|
1月前
|
XML Java 数据格式
Java-spring注解的作用
Java-spring注解的作用
23 0
|
2月前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit