Java 注解

发布时间:2024年01月10日

1 注解

1.1注解的理解

    1. 注解(Annotation)也被称为元数据(Metadata),用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息。
    1. 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息。
    1. 在 JavaSE 中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在 JavaEE 中注解占据了更重要的角
      色,例如用来配置应用程序的任何切面,代替 java EE 旧版中所遗留的繁冗代码和 XML 配置等。

1.2基本的 Annotation 介绍

使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成一个修饰符使用。用于修饰它支持的程序元

三个基本的 Annotation:

    1. @Override: 限定某个方法,是重写父类方法, 该注解只能用于方法-
    1. @Deprecated: 用于表示某个程序元素(类, 方法等)已过时
    1. @SuppressWarnings: 抑制编译器警告

1.3基本的 Annotation 应用案例

1.3.1 Override实例

package javaannotation;

public class OverrideDemo1 {
    public static void main(String[] args) {

    }
}

class Father{
    public void fly(){
        System.out.println("Father fly......");
    }
    public void say(){};
}

class Son extends Father{
    //1. @Override 注解放在 fly 方法上,表示子类的 fly 方法时重写了父类的 fly
    //2. 这里如果没有写 @Override 还是重写了父类 fly
    //3. 如果你写了@Override 注解,编译器就会去检查该方法是否真的重写了父类的
    // 方法,如果的确重写了,则编译通过,如果没有构成重写,则编译错误
    //4. 看看 @Override 的定义
    @Override
    public void fly() {
        super.fly();
    }

    @Override
    public void say() {
        super.say();
    }
}

1.3.2 SuppressWarnings实例

1. 当我们不希望看到这些警告的时候,可以使用 SuppressWarnings 注解来抑制警告信息
2. 在{""} 中,可以写入你希望抑制(不显示)警告信息
3. 可以指定的警告类型有
 all,抑制所有警告
 boxing,抑制与封装/拆装作业相关的警告
 cast,抑制与强制转型作业相关的警告
 dep-ann,抑制与淘汰注释相关的警告
 deprecation,抑制与淘汰的相关警告
 fallthrough,抑制与 switch 陈述式中遗漏 break 相关的警告
 finally,抑制与未传回 finally 区块相关的警告
 hiding,抑制与隐藏变数的区域变数相关的警告
 incomplete-switch,抑制与 switch 陈述式(enum case)中遗漏项目相关的警告
 javadoc,抑制与 javadoc 相关的警告
 nls,抑制与非 nls 字串文字相关的警告
 null,抑制与空值分析相关的警告
 rawtypes,抑制与使用 raw 类型相关的警告
 resource,抑制与使用 Closeable 类型的资源相关的警告
 restriction,抑制与使用不建议或禁止参照相关的警告
 serial,抑制与可序列化的类别遗漏 serialVersionUID 栏位相关的警告
 static-access,抑制与静态存取不正确相关的警告
 static-method,抑制与可能宣告为 static 的方法相关的警告
 super,抑制与置换方法相关但不含 super 呼叫的警告
 synthetic-access,抑制与内部类别的存取未最佳化相关的警告
 sync-override,抑制因为置换同步方法而遗漏同步化的警告
 unchecked,抑制与未检查的作业相关的警告
 unqualified-field-access,抑制与栏位存取不合格相关的警告
 unused,抑制与未用的程式码及停用的程式码相关的警告
4. 关于 SuppressWarnings 作用范围是和你放置的位置相关
package javaannotation;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings({"all"})
public class SuppressWarningDemo {
    public static void main(String[] args) {
        List list=new ArrayList<>();
        list.add("jack");
        list.add("tom");
        list.add("mary");
        int i;
        System.out.println(list.get(1));
    }
}

1.4 自定义注解

public @interface 注解名称{
public 属性类型 属性名() default 默认值

package javaannotation;

//自定义注解
public @interface MyAnnotation {
    //在注解中只能定义属性 public 属性类型 属性名() default 默认值
    /*
        属性类型必须是以下范围之一
        1.8种基本数据类型
        2.String类型
        3.Class类型
        4.枚举类型
        5.注解类型
        6.以上所有的类型的一维数组形式
    * */
    public String name();
    public double price() default 99.0;
}
@MyAnnotation(name = "测试") //没有指定price属性,默认为99
public class TestAnnotaion {
    @MyAnnotation(name="数据",price = 123)
    private String name;

    @MyAnnotation(name="构造方法")
    public TestAnnotaion(){

    }

    @MyAnnotation(name = "成员方法",price = 100)
    public void method(@MyAnnotation(name="参数") String msg){

    }
}

1.5元注解

元注解:就是修饰注解的注解

常见的元注解有两个

  • @Target:约束自定义注解只能在哪些地方使用
  • @Retention:声明注解的生命周期

Target中可以使用的值定义在ElementType枚举类中,常用的值如下
TYPE,类,接口
FIELD,成员变量
METHOD,成员方法
PARAMETER,方法参数
CONSTRUCTOR,构造器
LOCAL_VARIABLE,局部变量

package javaannotation.demo;

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

@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Book2 {
    public String value();

    public double price() default 99.0;

    public String[] author(); //有多个作者
}

Retention中可以使用的值定义在RetentionPolicy枚举类中,常用的值如下
SOURCE:注解只作用在源码阶段,生成的字节码文件中不存在
RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用)
CLASS:注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值

1.6注解解析

注解的解析

  • 注解操作中经常需要进行解析,注解析解析就是判断是不否存在注解,存在注解就解析出内容

与注解解析相关的接口

  • AnnotatedElement:该接口定义了与注解解析相关的解析方法

Annotation[] getDeclaredAnnotations():获得当前对象上的所有注解,返回注解数组
T getDecaredAnnotation(Class)annotationClass):根据注解类型获得注解对象
boolean isAnnotationPresent(ClassannotationClass)判断当前对象是否使用了指定的注解,如果是的话返回true,否则返回false

代码演示

package javaannotation.demo2;

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

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {
    public String value();
}
package javaannotation.demo2;

public class BookStore {
    @Book("Java入门") //注解析特殊作用:把value的值赋给当前成员变量
    private String bookName;//成员变量

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

}
package javaannotation.demo2;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class BookStroeTest {
    @Test
    public void testParse() throws NoSuchFieldException, InstantiationException, IllegalAccessException {
        //1.获取Class对象
        Class<BookStore> bookStoreClass=BookStore.class;
        BookStore bookStore = bookStoreClass.newInstance();
        //获取成员变量对象
        Field field=bookStoreClass.getDeclaredField("bookName");

        //私有成员变量
        field.setAccessible(true);

        //判断:成员变量上是否有BOOK注解
        if (field.isAnnotationPresent(Book.class)) {
            //有注解
            Book book=field.getDeclaredAnnotation(Book.class);
            //获取BOOK注解中的值
            String bookName=book.value();
            //使用反射技术给私有成员变量赋值
            field.set(bookStore,bookName);
        }
        System.out.println(bookStore.getBookName());
    }
}

文章来源:https://blog.csdn.net/lisus2007/article/details/135503490
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。