背景知识:
从JDK5开始提供名为Annotation(注释)的功能,它被定义为JSR-175规范。注释是以“@注释名”在代码中存在的,还可以添加一些参数
值,例如:@SuppressWarnings(value="unchecked")。注释可以附加在package, class,
method,
field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问。如果没有外部解析工具等对其加以解析和处理的情
况,本身不会对Java的源代码或class文件等产生任何影响,也不会对它们的执行产生任何影响。
元数据的作用,大致可分为三种:编写文档,通过代码里标识的元数据生成文档;代码分析,通过代码里标识的元数据对代码进行分析;编译检查,通过代码里标识的元数据让编译器能实现基本的编译检查。
JDK5内置的基本注释
JDK5内置了一些常用的注释,可以在编译时帮我们捕获部分编译错误,及提示信息,下面介绍下这些注释的用法:
1、@Override定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声
明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。例如我们为某类重写toString()方法却写成了
tostring(),并且我们为该方法添加了@Override注释;代码如下:
-
public
class
OverrideDemo{
-
@Override
-
public
Stringtostring(){
-
return
super
.toString();
-
}
-
}
public class OverrideDemo {
@Override
public String tostring() {
return super.toString();
}
}
在编译时,会提示以下错误信息:
引用
OverrideTest.java:4: 方法未覆盖其父类的方法
@Override
^1 错误
2、@Deprecated定义在java.lang.Deprecated中,此注释可用于修辞方法、属性、类,表示不鼓励程序员使用这样的元
素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。使用@Deprecated的示
例代码如下:
-
public
class
DeprecatedDemo{
-
public
static
void
main(String[]args){
-
DeprecatedClass.DeprecatedMethod();
-
}
-
}
-
-
class
DeprecatedClass{
-
@Deprecated
-
public
static
void
DeprecatedMethod(){
-
-
}
-
}
public class DeprecatedDemo {
public static void main(String[] args) {
DeprecatedClass.DeprecatedMethod();
}
}
class DeprecatedClass {
@Deprecated
public static void DeprecatedMethod() {
// TODO
}
}
在编译时,会得到以下提示信息:
引用
注意:DeprecatedDemo.java 使用或覆盖了已过时的 API。
注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。
如果在编译时添加-Xlint:deprecation参数,我们能更清楚的看到该警告的详细信息,如下:
引用
DeprecatedDemo.java:6: 警告:[deprecation] SomeClass 中的 DeprecatedMethod() 已过时
SomeClass.DeprecatedMethod();
^1 警告
要注意@Deprecated与@deprecated的区别,@deprecated是为了生成文档的需要,例如:
-
class
DeprecatedClass{
-
-
-
-
@Deprecated
-
public
static
void
DeprecatedMethod(){
-
-
}
-
}
class DeprecatedClass {
/**
* @deprecated 此方法已过时,不建议使用
*/
@Deprecated
public static void DeprecatedMethod() {
// TODO
}
}
3、@SuppressWarnings定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下:
通过上面的表格,你应该了解到每个参数的用意了,下面我就以一个常用的参数unchecked为例,为你展示如何使用@SuppressWarnings注释,示例代码如下:
-
import
java.util.List;
-
import
java.util.ArrayList;
-
public
class
SuppressWarningsDemo{
-
public
static
Listcache=
new
ArrayList();
-
-
public
void
add(Stringdata){
-
cache.add(data);
-
}
-
}
import java.util.List;
import java.util.ArrayList;
public class SuppressWarningsDemo {
public static List cache = new ArrayList();
//@SuppressWarnings(value = "unchecked")
public void add(String data) {
cache.add(data);
}
}
当我们不使用@SuppressWarnings注释时,编译器就会有如下提示:
引用
注意:SuppressWarningsDemo.java 使用了未经检查或不安全的操作。
注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。
下面我们去掉@SuppressWarnings(value="unchecked")这一行的注释符“//”,它会屏蔽编译时的警告信息,这也就是它所要达到的目的。
另外,由于@SuppressWarnings注释只有一个参数,并且参数名为value,所以我们可以将上面一句注释简写为
@SuppressWarnings("unchecked");
同时参数value可以取多个值如:
@SuppressWarnings(value={"unchecked", "deprecation"})
或@SuppressWarnings({"unchecked", "deprecation"})。
自定义Annotation注释
1、注释annotation与接口的异同:
因为annotation类型是一个非凡的接口,所以它与接口之间存在着某些差异:
A. Annotation类型使用关键字@interface而不是interface,这个关键字声明隐含了一个信息,它是继承了java.lang.annotation.Annotation接口,并非声明了一个interface。
B.
Annotation类型的方法定义是独特的、受限制的,方法必须声明为无参数、无异常抛出的。这些方法定义了annotation的成员:方法名成为了
成员名,而方法返回值成为了成员的类型。而方法返回值类型必须为primitive类型、Class类型、枚举类型、annotation类型或者由前面
类型之一作为元素的一维数组。方法的后面可以使用default和一个默认数值来声明成员的默认值,null不能作为成员默认值,这与我们在非
annotation类型中定义方法有很大不同。
C. Annotation类型又与接口有着近似之处,它们可以定义常量、静态成员类型(比如枚举类型定义)。Annotation类型也可以如接口一般被实现或者继承。
2、自定义注释的实例:
下面,我们将看到如何定义annotation类型的例子。它展示了annotation类型声明以及
-
@interface
与
interface
之间的不同:
-
-
import
java.lang.annotation.*;
-
-
-
-
public
@interface
Unstable{
-
}
@interface与interface之间的不同:
import java.lang.annotation.*;
/**
* 使用annotation来描述那些被标注的成员是不稳定的,需要更改
*/
public @interface Unstable {
}
下面的另一个例子只定义了一个成员。并通过将这个成员命名为value,使我们可以方便的使用这种annotation的快捷声明方式:
-
-
-
-
public
@interface
Author{
-
-
Stringvalue();
-
}
/**
* 使用Author这个annotation定义在程序中指出代码的作者
*/
public @interface Author {
/** 返回作者名 */
String value();
}
以下的例子更加复杂。Reviews annotation类型只有一个成员,但是这个成员的类型是复杂的:由Review
annotation组成的数组。Review
annotation类型有3个成员:枚举类型成员grade、表示Review名称的字符串类型成员Reviewer、具有默认值的字符串类型成员
Comment。
-
-
-
-
-
@Retention
(RetentionPolicy.RUNTIME)
-
public
@interface
Reviews{
-
Review[]value();
-
}
-
-
-
-
-
-
-
public
@interface
Review{
-
-
public
static
enum
Grade{EXCELLENT,SATISFACTORY,UNSATISFACTORY};
-
-
Gradegrade();
-
Stringreviewer();
-
Stringcomment()default
""
;
-
}
/**
* Reviews annotation类型只有一个成员,
* 但是这个成员的类型是复杂的:由Review annotation组成的数组
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Reviews {
Review[] value();
}
/**
* Review annotation类型有3个成员:
* 枚举类型成员grade、
* 表示Review名称的字符串类型成员Reviewer、
* 具有默认值的字符串类型成员Comment。
*/
public @interface Review {
// 内嵌的枚举类型
public static enum Grade { EXCELLENT, SATISFACTORY, UNSATISFACTORY };
// 下面的方法定义了annotation的成员
Grade grade();
String reviewer();
String comment() default "";
}
最后,我们来定义一个annotation方法用于罗列出类运行中所有的unchecked异常。这个
annotation类型将一个数组作为了唯一的成员。数组中的每个元素都是异常类。为了加强对未检查的异常(此类异常都是在运行时抛出)进行报告,我们
可以在代码中对异常的类型进行限制:
-
public
@interface
UncheckedExceptions{
-
Class[]value();
-
}
public @interface UncheckedExceptions {
Class[] value();
}
Meta-Annotation类型:
Annotation
类型可以被它们自己所标注。Java5.0定义了4个标准的meta-annotation类型,分别是:Target、Retention、
Documented、Inherited,它们被用来提供对其它annotation类型作说明。
这些类型和它们所支持的类在java.lang.annotation包中可以找到。
@Target的用法:
指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,以下这个注释只能用来声明方法:
-
@Target
(ElementType.METHOD)
-
public
@interface
MyAnnotation{
-
...
-
}
@Target(ElementType.METHOD)
public @interface MyAnnotation {
...
}
java.lang.annotation.ElementType是一个枚举类型,它具有以下定义:
@Retention的用法:
指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS,例如:
-
@Retention(RetentionPolicy.CLASS)
-
public
@interface
MyAnnotation{
-
...
-
}
@ Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {
...
}
java.lang.annotation.RetentionPolicy是一个枚举类型,它具有以下定义:
@Documented的用法:
指示某一类型的注释将通过 javadoc
和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented
来注释的,则其注释将成为注释元素的公共 API 的一部分。Documented是一个没有成员的注释。
@Inherited的用法:
指示注释类型自动被子类继承。 Inherited也是一个没有成员的注释。
注意,如果使用@Inherited注释类以外的任何事物都是无效的。还要注意,此元注释仅对从超类继承注释有效;对已实现接口的注释无效。
分享到:
相关推荐
Java Annotation 是 JDK5.0 引入的一种元数据机制,它允许程序员在代码中嵌入额外的信息,这些信息可以被编译器、构建工具或运行时系统用来执行特定的任务。Annotation 提供了一种安全、灵活的方式来描述代码的属性...
JDK 5.0引入了注解(Annotation),允许开发者在源代码中添加元数据,这其中包括了`@Deprecated`和`@Override`等预定义注解。`@Deprecated`标记不再推荐使用的API,编译器会发出警告。而`@Override`确保方法是重写...
Java JDK 5.0是Java开发工具包的一个重要版本,由Sun Microsystems在2004年发布,它引入了一系列重大改进和新特性,对Java编程语言产生了深远影响。本学习笔记将深入探讨JDK 5.0的关键知识点,帮助开发者理解和掌握...
良葛格的《Java JDK5.0学习笔记》是一本面向初学者的教程,旨在帮助读者掌握这个版本的核心概念和技术。以下是基于该书部分内容的知识点详解: 1. **泛型**:JDK 5.0引入了泛型,这是一种强大的类型系统增强,允许...
Java Annotation(注解)是自JDK 5.0开始引入的一种元数据,它提供了一种安全、非侵入式的方式来向编译器、虚拟机或者其他的工具提供关于代码的信息。这种信息可以用来进行编译时检查、运行时处理、代码生成等。注解...
- 注解(Annotation)是元数据的一种形式,Java 5.0引入了变量级别的注解,比如`@Deprecated`,用于标记过时的变量。 5. **增强的for循环(For-Each Loop)**: - Java 5.0引入的增强for循环简化了遍历数组和集合...
### JDK 5.0 新特性详解 #### 一、增强的 for 循环(ForEach Loop) JDK 5.0 引入了增强的 `for` 循环,也称为 foreach 循环,用于简化对集合和数组的操作。这种循环语法更加简洁,易于阅读。 **示例代码:** ``...
"SCJP考试模拟机——基于jdk5.0"是一款专门为准备SCJP考试的学员设计的模拟测试工具,它按照实际考试的标准和格式,帮助考生在家中或任何地方模拟真实的考试环境,提升备考效果。 这款模拟机的核心功能可能包括以下...
JSF+Spring+Hibernate(Annotation)的login小实例,建议入门的朋友看看,老鸟就免了,呵呵。环境:SQLSever2000+jdk5.0+spring2.0+hibernate3.2+jsf
在之后的JDK版本中,诸如注解(Annotation)、动态代理(Dynamic Proxy)、并行流(Parallel Streams)等新特性也被添加,这些都极大地丰富了Java语言的功能,提高了代码的可维护性和性能。 从提供的文件名来看,`...
JDK 5.0引入了一些重要的新特性,如泛型、枚举、变量args、增强的for循环(foreach)以及注解(Annotation),这些都对反编译工具提出了新的挑战。Jad158g声称能正确处理这些特性,提供准确的反编译结果,使得开发者...
我们有必要对JDK 5.0新增的注解(Annotation)技术进行简单的学习,因为Spring 支持@AspectJ,而@AspectJ本身是基于JDK 5.0的注解技术。所以学习JDK 5.0的注解知识有助于我们更好地理解和掌握Spring的AOP技术。 ...
这个版本需要配合JDK 5.0或以上,因为注解是JDK 5.0引入的一个重要特性。虽然较低版本的JDK也能通过Xdoclet实现元数据,但本文档专注于JDK 5.0的注解使用,对于Xdoclet的使用则不在讨论范围内。 【实体Bean】在...
Warp框架充分利用了JDK5.0的Annotation和泛型机制,并且基于Google Guice这个IoC框架,提供了full-stack的Web开发设施,他主要包含了四个部分: warp-persist框架:封装Hibernate和JPA,提供事务管理和持久化资源...