2023-09-23 16:15

Java中的注解

少尉

JavaEE

(180)

(0)

收藏

1.1. 理解Java注解

所有的注解类型都继承自接口Annotation。

我们之前常用的 @Override 就是一个注解。比如实现Runnable接口的代码:

class MyRunnable implements Runnable
{
    @Override
  public void run()
    {
  System.out.println("启动新线程");
       }
}

一旦编译器检测到某个方法被修饰了 @Override 注解,编译器就会检查当前方法的方法签名是否真正重写了父类的某个方法,也就是比较父类中是否具有一个同样的方法签名。

看看@Override的源码:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
 
}

反编译后会发现Override就是继承自Annotation:

public interface Override extends Annotation{
    
}

注解的本质就是一个继承了 Annotation 接口的接口。(接口可以继承接口,类只能实现接口)

1.2. 语法

定义一个注解:

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

上面的代码中@Documented, @Target, @Retention, @interface 都是来修饰 MyAnnotation 的,叫做元注解。

1.3. 元注解

元注解是用于修饰注解的注解。

元注解分类:

@Target:注解的作用目标

@Retention:注解的生命周期

@Documented:注解是否应当被包含在 JavaDoc 文档中

@Inherited:是否允许子类继承该注解

下面我们分开讲一下:

1.3.1. @Target

@Target 用于指明被修饰的注解最终可以作用的目标是谁,也就是指明,你的注解到底是用来修饰方法的?修饰类的?还是用来修饰字段属性的。

@Target的参数ElementType 是一个枚举类型,有以下一些值:

类型值

解释


ElementType.TYPE

注解作用在类、接口和枚举上

ElementType.FIELD

注解作用在属性字段上

ElementType.METHOD

注解作用在方法上

ElementType.PARAMETER

注解作用在方法参数上

ElementType.CONSTRUCTOR

注解作用在构造器上

ElementType.LOCAL_VARIABLE

注解作用在本地局部变量上

ElementType.ANNOTATION_TYPE

注解作用在注解上

ElementType.PACKAGE

注解作用在包上

 

1.3.2. @Retention

@Retention 用于指明当前注解的生命周期。

@Retention的参数RetentionPolicy 也是一个枚举类型,有以下一些值:

类型值

作用


RetentionPolicy.SOURCE

当前注解编译期可见,编译后会被丢弃,不会写入 class 文件

RetentionPolicy.CLASS

类加载阶段丢弃,会写入 class 文件

RetentionPolicy.RUNTIME

永久保存,可以反射获取


1.3.3. @Documented

@Documented用来注解是否应当被包含在 JavaDoc 文档中,注解以后当我们执行 JavaDoc 文档打包时会被保存进 doc 文档,反之将在打包时丢弃。

1.3.4. @Inherited

@Inherited 用来注解是否具有可继承性,也就说我们的注解修饰了一个类,而该类的子类将自动继承父类的该注解。

1.4. Java内置注解

除了上述四种元注解外,Java还有内置注解,主要有三种:

@Override

@Deprecated

@SuppressWarnings

1.4.1. @Override

用于标明此方法覆盖了父类的方法,源码如下:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
    }

它没有任何的属性,所以并不能存储任何其他信息。它只能作用于方法之上,编译结束后将被丢弃。

1.4.2. @Deprecated

用于标明已经过时的方法或类,源码如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

1.4.3. @SuppressWarnings

用于抑制编译器产生警告信息,源码如下:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
        String[] value();
}

其内部有一个String数组,主要接收值如下:

类型值

作用

 

deprecation

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

unchecked

执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型

fallthrough

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

path

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

serial

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

finally

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

unused

没有使用代码的警告

null

与null分析有关的警告

cast

强制转换相关的警告

rawtypes

使用泛型时忽略没有指定相应的类型

all

关于以上所有情况的警告

 

1.4.4. 内置注解示例

1、使用@Deprecated 示例:

//注明该类已经过时,不建议使用
@Deprecated
public class Test{
//注明该方法已经过时,不建议使用
   @Deprecated
public void test()
{
}
}

 

2、使用@SuppressWarnings示例:

(1) 忽略不指定类型和未检查转换警告

 没有使用@SuppressWarnings:

image.png

使用之后:

image.png 

(2)忽略没有使用代码的警告

没有使用@SuppressWarnings:

image.png 

使用之后:

image.png 

0条评论

点击登录参与评论