关于Java注解的一些解读

注解

什么是注解

注解是从JDK5.0开始引入的新技术,它不是程序本身,但是可以对程序做出解释,可以通过反射机制被其他程序,比如编译器读取,一般来说,我们使用@注解名来表示一个注解,当然其中也可以添加些参数值,比如@SuppressWarnings(value=“unchecked”)。我们可以将注解附加在package、class、method、field等上面,此时我们就相当于给他们添加了额外的辅助信息

内置注解

@Override:该注解定义在java.lang.Override中,只适用于修饰方法,表示该方法是对父类中的另一个相同方法的重写

@Deprecated:该注解定义在java.lang.Deprecated中,可以用于修饰方法、属性、类,表示不鼓励使用被该注解注解的元素,通常是因为它不安全或者已经过时

@SuppressWarnings:该注解定义在java.lang.SuppressWarnings中,可以用于抑制编译时的警告信息,但是它又于上述两个注解有所不同,它使用时需要添加参数:

参数名 作用
deprecation 使用了不赞成使用的类或方法时的警告
unchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型来指定集合的保存类型
fallthrough 当Switch程序块直接通往下一种情况而没有break时的警告
path 在类路径、源文件路径等中有不存在路径时的警告
serial 当在可序列化的类上缺少serialVersionUID定义时的警告
finally 任何finally子句不能正常完成时的警告
all 关于以上所有情况的警告

元注解

元注解就是注解其他注解的注解,Java中定义了4个标准的元注解类型,分别是@Target, @Retention, @Documented, @Inherited

@Target:用于描述注解的使用范围(即说明被描述的注解可以在什么地方使用,比如方法、属性之类的),该注解的参数有如下取值:

参数名 作用
ElementType.TYPE 表示该注解可以使用在类、接口(包括注释类型)、枚举的声明上
ElementType.FIELD 表示该注解可以用在字段的声明上,包括枚举常量的声明
ElementType.METHOD 表示该注解可以用在方法的声明上
ElementType.PARAMETER 表示该注解可以用在形参的声明上
ElementType.CONSTRUCTOR 表示该注解可以用在构造方法的声明上
ElementType.LOCAL_VARIABLE 表示该注解可以用在局部变量的声明上
ElementType.ANNOTATION_TYPE 表示该注解可以用在注解类型的声明上
ElementType.PACKAGE 表示该注解可以用在包的声明上
ElementType.TYPE_PARAMETER 表示该注解可以用在类型参数的声明上
ElementType.TYPE_USE 表示该注解可以用在类型的使用上

@Retention:用于表示需要什么级别保存该注解信息,用于描述注解的生命周期,有三种级别:SOURCE(注解仅保留在源文件中,当Java文件被编译成class文件时,注解会被遗弃), CLASS(注解保留到class文件,但是JVM加载class文件时会将注解遗弃), RUNTIME(注解不仅保存到class文件中,JVM加载class文件后,仍然存在)

@Documented:表示是否将注解生成在javadoc中

@Inherited:表示子类可以继承父类中的该注解

自定义注解

使用@interface来自定义注解

解释下该方式的一些注意事项:

1、该写法已经自动继承了java.lang.annotation.Annotation接口

2、该接口里的每个方法实际上是声明了一个配置参数,并且方法的名称就是参数的名称,返回值的类型就是该参数的类型(返回值只能是基本类型、Class、String、enum)

3、可以使用default来声明参数的默认值

4、如果只有一个参数成员,一般参数名为value,这是因为我们在使用该注释时,书写参数可以直接省略value=,直接写参数值,如果是其他情况的话,则必须参数名=参数值

5、注解元素必须要有值,我们定义注解元素时,经常使用空字符串、0作为默认值

下面通过代码对这些注意事项进行解释:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public class Test {
    
    

    // 因为我设置了注解参数的默认值为"",所以此处不写参数也不会报错,但是如果我没写参数的默认值,由于注释接口里定义了参数,所以必须得写上参数,如果没定义的话,也可以不用写
    @MyAnnotation
    public void test() {
    
    

    }
}

@Target({
    
    ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    
    
    // 注解的参数: 参数类型 + 参数名 + () + [default 默认值]
    String value() default "";
}

如果某参数的默认值设置为-1,则可以代表该参数可能不存在

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({
    
    ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    
    
    int value() default -1;
}

注解有多个参数时可以没有顺序,只需要用 参数名=参数值 的方式书写即可

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public class Test {
    
    
    @MyAnnotation(id=0, name="Warren", age=18)
    public void test(){
    
    
    }
}

@Target({
    
    ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    
    
    String name();
    int age();
    int id();
}

猜你喜欢

转载自blog.csdn.net/myWarren/article/details/109364349