Java中的注解剖析
在Java当中设定了许多"注解",不仅能够使程序更加容易理解,而且能够对特定的程序段进行检查
增强程序的安全性,在java当中有 内置的注解 和 自定义的注解 两种,下面进行介绍
一、内置的注解
1、内置的注解有三种,都是java语言内部已经定义好的注解,用于实现部分功能
分别是:@Override(继承)、@Deprecated(不赞成)、@SuppressWarnings(禁止警告)
他们所在的类分别是 java.lang.Override/java.lang.Deprecated/java.lang.SupressWarnings
@Override:表示当前注解的方法将重写父类当中的对应的方法,如果不符合重写的规则,那么
程序在编译时就会报错
@Deprecated:该注解用在那些已经废弃了的(即在以后不打算在用的)类或方法前面,如果
某个方法或类已经被该标签注解过了,那么如果接下来程序中又用到了该方法
或者类的话,那么程序就会有产生警告 @SuppressWarnings:关闭指定的编译警告信息,即强制编译器不发出警告
其中前两个标签都是没有参数的,只要将对应的标签写在相应的程序元素的前面就行了,
一般所有的注解都写在程序元素的前面,而且要单独一行
如:
@Override
public boolean equals(Object obj){.....}
2、当程序当中有许多的不可避免的警告时,那么在输出窗口当中就会出现非常多的警告文字,使得
程序变的臃肿,那么这时@SuppressWarnings就派上用场了,将@SuppressWarnings写在想要屏蔽、
警告的程序元素的前面就能够将警告屏蔽,该标签能够用于类和方法,如果用在类的前面的话
那么意味着类中的所有的成员都将被施加该注解,所以,建议将该标签尽量的用在恰当的范围内
该方法应有String[]类型的参数,这些参数指定了到底屏蔽那些类型的警告,形式如下:
① 当只有一个参数时,可以使用下面的两种形式:
@SuppressWarnings(value={"unchecked"})
@SuppressWarnings ("unchecked")
②当具有多个参数时,那么形式为:
@SuppressWarnings ({"unchecked","deprection"})
至于参数具体是什么可以根据程序中出现的警告语句来确定,
比如在没有加入该标签时出现了警告,我们会发现该语句开头当中有该警告的英文参数
如:warning : [deprection] StringBuffer InputStream in java.io has been deprecated
那么这个[deprection]就是噶出警告的英文参数,所以确定参数并不是问题
二、自定义注解
自定义注解就是说可以自己定义注解,一般来说自己定义的注解只是用来使程序更加易读,只是提供一 些信息,自定义注解分成三类:没有任何元素的注解、只有一个元素的注解、有多个元素的注解
自定义的注解的形式实际就是在interface前面加上一个标示符@,自定义的注解和内置的注解使用方法
是一样的,都是使用在程序元素前面,单独成一行
还有一点需要注意的是自定义的注解和声明一个接口/类相似,也有访问权限修饰符
自定义的注解自动继承 java.lang.annotation.Annotation接口
①没有任何元素的注解:
public @interface WorkInProgress{ }
@WorkInProgress
public static float computeTax()
{return 0.0 ;}
没有任何元素的注解只能通过名字祈祷一种标示作用,不能显示其他的信息
如,上述的注解用在该方法前面,通过名字WorkInprogress可以提示说computeTax方法还没有
写完
②单值注解
public @interface Task
{ String value();
}
使用方式如: @Task("Implement tax computations")
注意单值注解的声明的内部一般都用value这个名字,如果用其他的名字,则在使用该注解时
必须明确指出这个名字 如:
public @interface Task
{ String description(); }
使用方法如:@Task(description="Implement tax computations")
③多值注解
public @interface Task
{ String description();
String targetDate();
int esimateHours();
String addtionalNote(); }
使用方法:@Task(description="Implement tax computations",
targetDate="Jan 1 , 2014",
esimateHours=50,
addtionalNote="Implement" )
不论是单值还是多指都只是通过那些名字和 = 后面的参数来提供一些信息,别无其他
值得注意的是: ①java允许为注解的成员指定默认值,同过default关键字完成,
比如,若为上面的成员 String description()指定默认值,就将之写成:
String description() defualt "Implement tax computations" ;
在使用标签时不给该成员赋值,那么,就是用该默认的值 ② 创建自定义注解时应遵守规则:
为了创建注解参数,就必须声明不包含任何参数的方法
方法不能包含任何throws,extends的子句
方法的返回值应该为:基本类型、String、类、枚举 等
三、我们还可以为注解添加注解,这样的注解称为元注解
java目前定义了4种元注解:
@Target
@Retention @Documented
@Inherited
这四种注解元枚举变量都位于java.lang.annotation包当中,所以在使用这四种元注解前
必须添加语句:
import java.lang.anntation.Annotation;
1、@Target该标签用于指定一个注解可以用于哪些程序元素,通过实例会非常容易理解其用法:
如:
@Target(ElementType.METHOD)
public @interface Bbp
{ ....... }
程序当中为Bbp注解添加了注解@Target(ElementType.METHOD),其中的METHOD就限定了
Bbp注解只能用于方法,即只能注解方法,否则会报错;ElementType还有很多类型用来规定
注解可用的不同的位置:
ElementType.FIELD:可以用于字段(字段的范围很宽泛)
ElementType.METHOD:可以用于方法
ElementType.PACKAGE:可以用于包
ElementType.TYPE:可以用于 类、接口、enum、 ElementType.LOCAL_VARIABLE:可以用于局部变量 2、@Retention:由于该元注解有很多的注意事项,所以我们将该元注解单独的记录在一个.doc文件当中
见该doc文档
3、@Documented:
当一个注解被@Documented注解时,就意味着当使用javadoc工具生成源代码的HTML格式的API文档时,
这个注解是能看见的,如:
package rog.myPackage ;
import java.lang.annotation.Annotation;
@Documented @interface WorkInProgress{}
@Documented @interface Task { String str();
int value(); }
public class Hellow
{ @WorkInProgress
@Task(str="you are right",value=10)
public static void main(String[]args) { return; } }
假设该文件为Hellow.java 文件的话,那么如果使用javadoc工具时:
javadoc Hellow.java
在生成的index.html文档中,会有这样的文字:
“方法的具体解释为 main
@WorkInProgress
@Task(str="you are right",value=10)
public static void main(String[]args)”
可见将@workInprogress 和 @Task 的内容都保存到了文档当中,这解释main方法提供了详细的解释
而在源文件当中使用//或/**....*/是不会在index.html文档中留下任何痕迹的
4、@Inherited
如果某个注解标记了某个类的话,同时这个注解又使用了这个元注解的话,那么当某个子类
继承这个父类时,标记父类的注解就同时被子类继承了,这是非常有用的,
比如说,某个父类还没有被完成,这是我们用一个@NoFinished对值进行注解,如果某个子类
继承了这个父类的话,因为父类没有完成,那么子类就没有完成,这样我们对@NoFinish使用
@Inherited元注解,那么子类自然就继承了这个@NoFinished注解,在实际中由于程序非常的
长,那么,使用这个元注解对于程序的校检是非常有帮助的

浙公网安备 33010602011771号