注解的作用 常用注解

注解是告知编译器要做什么事情的说明,在程序中可以对任何元素进行注解,包括Java包、类、构造方法、域、方法、参数以及局部变量。

注解就像修饰符一样,使用时在其前面增加@符号,用于修饰包、类、构造方法、域、方法、参数以及局部变量的声明,这些信息被存在注解的“name=values”键值对中。注解不影响程序代码的运行,无论增加还是删除注解,代码都始终如一的执行。如果希望程序中的注解在运行时起到一定作用,需要通过配套的工具对注解中的信息进行访问和处理,这种工具统称为APT(Annotation Processing Tool,注解处理工具)。

APT注解处理工具负责提取注解中包含的元数据,并会根据这些元数据增加额外功能。注解中元数据的作用有以下三个方面:

  1. 编写文档——通过注解中标识的元数据可以生成doc文档
  2. 代码分析——通过注解中标识元数据对代码进行分析
  3. 编译检查——通过注解中标识的元数据,让编译器能够实现基本的编译检查,例如@Override重写

Java.lang.annotation.Annotation是一个借口,该接口是所有注解类型都要扩展的公共借口,但接口本身不能定义注解类型,且手动扩展该公共接口的接口也不能定义注解类型

基本注解

@Override:用于限定重写父类的方法,使用该注解修饰的方法必须重写父类中的方法,否则会发生编译错误

@Deprecated:用于标记某个元素已过时,当程序使用已过时的类、方法等,编译器会给出警告;

@SuppressWarnings:用于抑制编译警告的发布,允许开发人员取消显示指定的编译器警告

@SafeVarargs:用于抑制“堆污染”警告

@FunctionalInterface:用于指定某个接口必须是函数式接口

@Override注解

@Override注解用于指定方法的重写,强制一个子类必须覆盖父类的方法。使用@Override注解非常简单,就是需要在重写的方法前加@Override修饰,语法格式如下:

@Override
[访问符] 返回类型 重写方法名(){...}

@Override注解只能修饰方法,不能修饰其他程序元素。@Override注解可以帮助程序员避免一些低级错误

@Deprecated注解

@Deprecated注解标示某个程序元素(接口、类、方法等)已过时,使用该注解的语法格式如下

@Deprecatad
//接口、类、方法等程序元素定义

@Deprecated注解的作用与文档注释中的@deprecated标记的作用基本相同,但使用方式不同,@Deprecated无需放在文档注释/**...*/中,而是直接在接口、类或方法前进行修饰。

@SuppressWarnings注解

SuppressWarnings注解允许开发人员控制编译器警告的发布,可以标注在类、字段、方法、参数、构造方法以及局部变量上。@SuppressWarnings注解的语法格式如下

@SuppressWarnins("参数")
//程序元素(包括该元素的所有子元素)

常用值:

all——忽略所有警告

boxing——忽略装箱/拆箱操作所产生的警告

deprecation——忽略@Deprecated注解的已过时类、方法所显示的警告

finally——忽略finally子句无法正常完成的警告

fallthrough——忽略switch程序块中没有使用break的警告

rawtypes——忽略因使用泛型时未限制类型而产生警告

serial——忽略类缺少serialVersionUID的警告

unchecked——忽略未经检查的类型转换警告

unused——忽略已定义但从未使用的警告

@SafeVarargs注解

“堆污染”是将一个不带泛型的变量复制==赋值给一个带泛型的变量,将导致泛型变量污染。下述代码就会发生这种“堆污染”

List list = new ArrayList();  //没有使用泛型限制的集合
list.add(10);                 //未经检查的类型转换,unchecked警告
List<String>ls = list;        //发生堆污染
System.out.println(ls.get(0));//产生ClassCastException异常

如果不希望看到堆污染警告,可以使用下面三种方式来抑制堆污染警告:

  • 使用@SafeVarargs注解修饰引发该警告的方法(推荐)
  • 使用@SuppressWarnins("unchecked")修饰
  • 编译时使用-Xlint:varargs选项
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class SafeVarargsDemo {
    @SafeVarargs
    public static void faultyMethod(List<String>... listStrArray){
        //Java语言不允许创建泛型数组,因此listArray只能被当成List[]处理
        //此时相当于把List<String>赋给了List,已经发生了“擦除”
        List[] listArray = listStrArray;//发生堆污染
        List<Integer>myList = new ArrayList<Integer>();
        myList.add(new Random().nextInt(100));
        //把listArray的第一个元素赋为myList
        listArray[0] = myList;
        String s = listStrArray[0].get(0);
    }

    public static void main(String[] args) {
        faultyMethod(Arrays.asList("Hello!"),Arrays.asList("World!"));
    }
}

上述代码定义了一个faultyMethod()方法,该方法使用可变参数,个数可变的形参相当于数组,但是形参的类型又是泛型,而Java是不支持泛型数组的,因此只能将List<String>...当成List[],从而导致堆污染。此时使用@SafeVarargs注解来修饰FaultyMethod()方法,在调用该方法时不会发出堆污染警告。

@FunctionalInterface注解

@FunctionalInterface注解用于指定某个接口必须是函数式接口(如果一个接口中只有一个抽象方法,则该接口就是函数式接口)

FunctionalInterface注解的使用

@FunctionalInterface
public interface FunctionalInterfaceDemo {
    static void foo() {
        System.out.println("foo类方法");
    }

    default void bar() {
        System.out.println("bar默认方法");
    }

    void test();//只定义一个抽象方法
    //void abc(); //再增加一个抽象方法就错了
}

在接口前使用@FunctionalInnterface注解进行修饰,则该接口内只允许定义一个抽象方法;将倒数第二行代码取消注释时,该接口拥有两个抽象方法而导致程序报错。

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值