Annotation注释(⼀)——java学习笔记
以下内容⼤部分来⾃于疯狂java⼀书和廖雪峰⽼师的教程,如需转载请注明这两个出处,本⽂仅供⾃⾝学习,查缺补漏之⽤。
初识注解
从JDK5开始,java正价了对元数据(metadata)的⽀持,也就是annotation(即朱,也被翻译为注释),这种annotation与之前所说的注释有⼀定的区别。本章所介绍的annotation,其实是代码⾥的特殊标记,这些标记可以在编译、类加载、运⾏时被读取,并执⾏相应的处理。通过使⽤朱,程序开发⼈员可以在不改变原有逻辑的情况下,在源⽂件中嵌⼊⼀些补充信息。代码分析⼯具、开发⼯具和部署⼯具可以通过这些补充信息进⾏验证或进⾏部署。
注解是什么??
注解(Annotation)是放在Java源码的类、⽅法、字段、参数前的⼀种标签。
注解的作⽤:
注解本⾝对代码逻辑没有任何影响
如何使⽤注解由⼯具决定。
编译器就是⼀种⼯具
编译器可以使⽤的注解:
@Override:让编译器检查该⽅法是否正确实现了覆写
@Deprecated:告诉编译器该⽅法已经被标记为“作废”,在其他地⽅引⽤将会出现编译警告
@SuppressWarnings如果编译器发现在以下的代码中出现了警告,那么请编译器忽略这些警告。
annotation提供了⼀种为程序元素设置元数据的⽅法,从某些⽅⾯来看,annotation就像修饰符⼀样,可以终于修饰包、类、构造器、⽅法、成员变量、参数、局部变量的⽣命,这些信息被储存在annotation的“name = value”对中。
annotation是⼀个接⼝,程序可以通过反射来获取指定程序元素的annotation对象,然后通过annotation对象来去的注解⾥的元数据,⼤家需要注意本⽂中使⽤annotation的地⽅,有的annotation指的是java.lang.annotaion接⼝,有的指注解本⾝
annotation能被⽤来作为程序员苏(类、⽅法、成员变量等)设置元数据,值得提出的是,annotation不影响程序代码的执⾏,⽆论增加、删除annotation,代码都始终如⼀的执⾏,如果希望让程序中的annotation在运⾏时起⼀定的作⽤,,只有通过某种配套的⼯具对annotation中的信息进⾏访问和处理,访问和处理annotation的⼯具统称APT(Annotation Processing Tool),不是ATP。=。=
学习java的学习方法注解可以定义配置参数:
配置参数由注解类型定义
配置参数可以包括:
所有基本类型
String
枚举类型
数组
配置参数必须是常量
关于配置参数的部分注意事项:
缺少某个配置参数将使⽤默认值(如何设置默认值下⽂会有详细说明)
如果只写常量,相当于省略了value参数
如果只写注解,相当于全部使⽤默认值
基本annotation
Annotation必须使⽤⼯具来处理,⼯具负责提取annotation⾥包含的元数据,⼯具还会根据这些元数据增加额外的功能。在系统学习⼼得annotation语法之前,我们先看⼀下java提供的5个基本annotation的⽤法——使⽤annotation时要在其前⾯加@符号,并把该annotation当成⼀个修饰符使⽤,⽤于修饰它⽀持的程序元素。
5个基本的annotation如下:
@Override
@Dprecated
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
上⾯5个基本annotation中的@SafeVarargs是java 7 新增的、 @FunctionalInterface是java 8 新增的,这5个基本的annotation都定义在java.lang包下,我们可以通过查看他们的api⽂档来了解他们的具体细节。下⾯进⾏简单的介绍。
限定重写⽗类⽅法:@Override
这个可能是我们学习java的时候最先接触的注解,当然那时我们可能不清楚它是什么。
@Override就是⽤来指定⽅法覆载的,它可以强制⼀个⼦类必须覆盖⽗类的⽅法。如下程序中使⽤@Override指定⼦类Apple的info()⽅法必须重写⽗类⽅法。
它的主要作⽤就是帮助程序员避免⼀些低级错误,例如把上⾯apple类中的info⽅法不⼩⼼写成了inf0。这⼀点有时候很有必要。
另外还有⼀点要提出的就是 apple的红线是因为此⼯程中还有同名的类名,和本程序的对错⽆关,所以⼤家忽略掉这些就可以了。
标记已过世:@Deprecated
@Deprecated⽤于表⽰某个程序元素(类、⽅法等)已过时,当其他程序使⽤已过时的类、⽅法时,编译器将会发出警告。如下程序制定apple类中的info()⽅法已过世,其他程序中使⽤apple类的info()⽅法时编译器将会发出警告。
注意:
@Deprecated的作⽤与⽂档注释中的@deprecated标记的作⽤基本相同,但它们的⽤法不同,前者是JDK5 才⽀持的注解,⽆须放在⽂档注释语法(/* …*/部分)中,⽽是直接⽤于修饰程序中的程序单元,如⽅法、类、接⼝等。
抑制编译器警告:@SuppressWarnings
@SuppressWarnings指⽰该被Annotation修饰的程序员苏(以及该程序元素中的所有⼦元素)取消显⽰指定的编译器警告。
@SuppressWarnings会⼀直作⽤域该程序元素的所有⼦元素,例如,使⽤@SuppressWarnings修饰某个类取消显⽰某个编译器警告,同时⼜修饰该类⾥的某个⽅法取消显⽰另⼀个编译警告,那么⽅法将会同时取消显⽰这两个编译器警告。
在通常情况下,如果程序中使⽤没有泛型限制的集合将会引起编译器警告,为了避免这种编译器警告,可以使⽤@SuppressWarnings修
饰,下⾯程序就取消了没有使⽤泛型的编译器警告。
①如果删除注释,这个地⽅就会有编译器的警告。这个成员变量的设置,可以参考下⼀篇注释的⽂章。
java 7 的“堆污染”警告与@SafeVarargs
Java把引发这种错误的原因成为“堆污染”,当吧⼀个不带泛型的对象赋给⼀个带泛型的变量时,往往就会发⽣这种堆污染,如①所表⽰对于形参个数可变的⽅法,该形参的类型⼜是泛型,这将更容易导致“堆污染”,如下
List list = new ArrayList<Integer>();
list.add(20);//添加元素时引发unchecked 异常
/
/下⾯代码引起“未经检查的转换”的警告,编译、运⾏时完全正常
List<String> ls = list; //①
//但只要访问ls ⾥的元素,如下⾯代码就会引起运⾏时异常
System.out.(0));
List ls = list;已经发⽣了堆污染,由于该⽅法有个形参是List类型,个数可变的形参相当于数组,但Ja
va⼜不⽀持泛型数组,因此程序只能把list当成List[]处理,这就发⽣了堆污染
但是这⾥有个值得注意的问题 ,就是java6和更早的版本,Java搬⼀起认为faultyMethod()⽅法完全没有问题,既不会提⽰错误,也没有提⽰警告
编译该程序将会在①处引发⼀个unchecked警告。这个警告出现的⽐较突兀(书中就是这么写的),定义faultyMethod()⽅法时没有任何警告,调⽤该⽅法时去引发了⼀个警告。
从Java7开始就会在编译ErrorUtils时就会发出⼀个警告,这样保证开发者“更早”地注意到程序中可能存在的“漏洞”
但在有些时候,开发者不希望看到这个警告,则可以使⽤如下三种⽅式来“抑制这个警告”
使⽤@SafeVarargs修饰引发该警告的⽅法或构造器
使⽤@SuppressWarnings(“unchecked”)修饰
编译时使⽤-Xlint:varargs选项
前两种明显⽤的⽐较多,如果程序使⽤@SafeVarags修饰ErrorUtils类中的faultyMethod()⽅法,则编译上⾯两个程序时都不会发出任何警告。
Java8的函数式接⼝与@Funtionallnterface
Java8 规定,如果接⼝中只有⼀个抽象⽅法(可以包含多个默认⽅法或多个static⽅法),该接⼝就是函数式接⼝。@Funtionallnterface 就是⽤来指定某个接⼝必须是函数是借⼝。例如,如下程序使⽤@Funtionallnterface修饰了函数式接⼝
函数式接⼝就是为了Java8的lambda表达式准备的,Java8允许使⽤lambda表达式创建函数式接⼝的实例,因此Java8专门增加了@Funtionallnterface
@Funtionallnterface告诉编译器检查这个接⼝,保证该接⼝只能包含⼀个抽象⽅法,否则就会编译出错。@Funtionallnterface主要是帮助程序员避免⼀些低级错误,例如,在上⾯的funinterface接⼝中再增加⼀个抽象⽅法abc()编译程序时将出现如下错误提⽰
@Funtionallnterfac只能修饰接⼝,不能修饰其他程序元素。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论