从JDK5开始,Java增加了对元数据的支持,也就是Annotation(即注解也被翻译为注释)。

这里的Annotation和普通的注释有一定的区别,它是代码中的特殊标记,这些标记可以在编译、类加载或者运行时被读取,并执行相应的处理。通过这样的注解,可以帮助开发人员在不改变原有的逻辑的情况下,在源文件中补充一些信息。而代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。

Annotation可以用来为程序元素(类、方法、成员变量等)设置元数据,值得一提的是,它不会影响代码的执行。

Java提供了5个基本Annotation的用法——使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符来使用。

5个基本的Annotation如下:

  1. @Override
  2. @Deprecated
  3. @SuppressWarnings
  4. @SafeVarargs
  5. @FunctionalInterface

@Override

@Override用来指定子类必须覆盖父类的方法

public class Fruit {
public void info(){
System.out.println("Fruit");
}
}
class Apple extends Fruit{
@Override
public void info(){
System.out.println("Apple");
}
}

编译上面的程序,可能丝毫看不出@Override的用处所在,因为它的作用是告诉编译器检查这个方法,保证父类要包含一个被该方法重写的方法,否则会编译出错。

使用@Override可以避免开发人员不小心将info方法写成了inf0方法,这样的低级错误可能会成为后期排错时的巨大障碍。

@Deprecated

@Deprecated用来表示某个程序元素(类、方法等)已经过时,当其他程序使用已经过时的类或者方法时,编译器将会给出警告。

@SuppressWarnings

@SuppressWarnings指示由它修饰的程序元素以及该元素中的所有子元素取消显示指定的编译器警告。

@SuppressWarnings(value="all")
public class Fruit {
public static void main(String[] args){
Fruit.info();
}
@Deprecated
public static void info(){
System.out.print("Fruit");
}
}

参考上面的代码,当使用了“@SuppressWarnings(value=”all”)”之后,编译器会取消使用了已经被弃用的方法的警告。value变量的值为你希望抑制的警告。

“堆污染”警告与@SafeVarargs

List ls = new ArrayList<Integer>();
ls.add(20);//添加元素时会引发unchecked警告
//下面的代码会引发“未经检验的转换”的警告,但是编译、运行时完全正常
List<String> list = ls;
//但是只要访问其中的元素,下面代码就会引起运行时异常
System.out.print(list.get(0));

Java将引发这种错误的原因称为“堆污染”。当把一个不带泛型的对象赋给一个带泛型的对象时,往往就会产生这种“堆污染”。

class UnSafeVarargs
{
static <T> T[] foo(T... args) {
return args;
} static <T> void bar(T... args) {
for(T x : args) {
System.out.print(x);
}
}
}

考虑上面这段程序,编译器会在方法定义处提示“Possible heap pollution from parameterized vararg type”。这是因为对于形参的个数可变且又是泛型时,当后续的代码依赖于传入的args中的每个元素的话,它是安全的。如果后续的代码依赖于args整体是T类型的数组的话,它将是不安全的。因为其中的元素可能是整型,也可能是字符串。程序会尝试将它转换成一个T类型的数组并且失败。

因此上面的两个方法中,前者是不安全的,后者是安全的。

在有些时候,开发者不希望看到这个“堆污染”的警告,那么就可以使用以下三种方式来抑制这个警告:

  1. 使用@SafeVarargs修饰引发该警告的方法或者构造器
  2. 使用@SuppressWarnings(“unchecked”)修饰。
  3. 编译时使用-Xlint:varargs选项

显然第三种方式很少用到,通常选择前两种,尤其是第一种,因为它是专门为抑制“堆污染”警告而提供的。

@FunctionalInterface

如果接口中只有一个抽象方法(可以包括多个默认方法或者多个static方法),该接口就是函数式接口。@FunctionalInterface就是用来指定某个接口必须是函数式接口的。

如果使用了@FunctionalInterface的接口不是函数式接口,那么编译就会出错。它和@Override一样,都是为了帮助程序员避免一些低级错误的。

Java五种基本的Annotation,提高程序的可读性的更多相关文章

  1. 1、如何在列表,字典,集合种根据条件筛选数据?2、如何为元组中的每个元素命名,提高程序的可读性3、如何统计出序列中元素出现的频度4、如何根据字典中value的大小,对字典的key进行排序

    一.数据筛选: 处理方式: 1.filter函数在py3,返回的是个生成式. from random import randint data = [randint(-100,100) for i in ...

  2. Java五种单例区别

    详细请参考如下链接: http://www.voidcn.com/article/p-shzgsluz-bqa.html https://blog.csdn.net/android_freshman/ ...

  3. python 学习笔记(二):为元组的每个元素命名,提高程序的可读性

    在程序中有些数据为固定格式时,即字段数量确定.字段位置顺序确定不变,我们就可以用元组来储存.使用元组的优势是储存空间很小,访问速度也很快.如下代码对每个学生信息用元组来表示: # ('Jim', 16 ...

  4. 五种方式让你在java中读取properties文件内容不再是难题

    一.背景 最近,在项目开发的过程中,遇到需要在properties文件中定义一些自定义的变量,以供java程序动态的读取,修改变量,不再需要修改代码的问题.就借此机会把Spring+SpringMVC ...

  5. java线程池与五种常用线程池策略使用与解析

    背景:面试中会要求对5中线程池作分析.所以要熟知线程池的运行细节,如CachedThreadPool会引发oom吗? java线程池与五种常用线程池策略使用与解析 可选择的阻塞队列BlockingQu ...

  6. 【开发笔记】- Java读取properties文件的五种方式

    原文地址:https://www.cnblogs.com/hafiz/p/5876243.html 一.背景 最近,在项目开发的过程中,遇到需要在properties文件中定义一些自定义的变量,以供j ...

  7. 细说进程五种状态的生老病死——双胞胎兄弟Java线程

    java线程的五种状态其实要真正高清,只需要明白计算机操作系统中进程的知识,原理都是相同的. 系统根据PCB结构中的状态值控制进程. 单CPU系统中,任一时刻处于执行状态的进程只有一个. 进程的五种状 ...

  8. 改善C#程序,提高程序运行效率的50种方法

    改善C#程序,提高程序运行效率的50种方法   转自:http://blog.sina.com.cn/s/blog_6f7a7fb501017p8a.html 一.用属性代替可访问的字段 1..NET ...

  9. Java 字符串拼接 五种方法的性能比较分析 从执行100次到90万次

    [请尊重原创版权,如需引用,请注明来源及地址] > 字符串拼接一般使用“+”,但是“+”不能满足大批量数据的处理,Java中有以下五种方法处理字符串拼接,各有优缺点,程序开发应选择合适的方法实现 ...

随机推荐

  1. CSS中的px与物理像素、逻辑像素、1px边框问题

    一直不太清楚CSS中的1px与逻辑像素.物理像素是个什么关系(作为一名前端感觉很惭愧 -_-!),今天终于花时间彻底弄清楚了,其实弄清楚之后就觉得事情很简单,但也只有在弄清楚之后,才会觉得简单(语出& ...

  2. Kali学习笔记9:端口扫描详解(上)

    UDP端口扫描: 原理:回应ICMP不可达,代表端口关闭:没有回应,端口开启 建议了解应用层的UDP包头结构,构建对应的UDP数据包用来提高准确度 另外:所有的扫描都存在误判情况 我们用Scapy写个 ...

  3. OAuth2.0深入理解

    1. OAuth2.0深入理解 1.1. 概念 OAuth(Open Authorization)开放授权,表示将系统功能部分授权给第三方系统调用,实现更细颗粒度的权限控制 OAuth是一种在线授权或 ...

  4. ubuntu下opencv的版本切换及遇到的问题解决

    默认使用opencv 3.2的时候,使用SVM的时候,系统报错如下: error: ‘class MySVM’ has no member named ‘decision_func’ 解决方法:要把系 ...

  5. RISC-V指令集介绍 - 整数基本指令集

    1. 寄存器 32个x寄存器,RV32下x reg是32位宽 x0:硬连线 常数0 专门的零寄存器 x1-x31:31个通用reg 返回地址:没有强制要求那一个x作为lr,但是一般用x1 pc:额外的 ...

  6. npm ERR! Refusing to install package with name "webpack" under a package -----

    当我们在安装以一些依赖的时候会提示以下报错--------- 问题出在: 这个name 不能使用所需要安装包的名字! 解决方案----- 修改下就行 -- -我将wenpack 改成webpack1 ...

  7. git提示error setting certificate verify locations以及fatal: unable to access 的解决办法

    z当使用git ------上传文件到GitHub上时!~~~出现了以下错误  :fatal: unable to access ' 可以采用以下解决方式: 修改GitHub上的地址格式=====ht ...

  8. PostgreSQL踩坑现场

    1.PostgreSQL表名.字段名.别名等大小敏感,默认都会转化成小写形式.如果名字中有大写字母,必须分别添加双引号.在写后台时,注意添加\ 如表名:TestTable中有个字段名userName ...

  9. spring boot -整合Ehcahe

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...

  10. Vue : Expected the Promise rejection reason to be an Error

    在vue项目中添加ESLint,new 一个 Promise 一直显示错误 :Expected the Promise rejection reason to be an Error 正常来说new ...