Java 注解(一)

注解,也被称为元数据,为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。
注解是众多引入到Java SE5中的重要语言变化之一。他们可以提供用来完整的描述程序所需的信息,而这些信息无法用Java来表达的。
注解的语法也比较简单,除了@符号的使用之外,它基本上与Java固有的语法一致。Java SE中内置了三种,定义在java.lang中的注解:

  • @override,表示当前的方法定义将覆盖超类中的方法,如果你一不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示。
  • @Deprecated,如果程序员使用了注解为他的元素,那么编译器会发出警告信息。
  • @SuppressWarnings,关闭不当的编译器警告信息。在Java SE5之前的版本中,也可以使用注解,不过它会被忽略不起作用。

java还另外提供了四种注解,专门负责新注解的创建。稍后会说到。

1、基本语法

在下面的例子中,使用@Test对testExecute()方法进行注解。该注解本身并不做任何事情,但是编译器要确保在其构造路径上必须有@Test注解的定义,程序员可以创建一个通过反射机制来运行testExecute()方法的工具。

package annotations;
import net.mindview.atunit.*;
public class Testable {
    public void execute() {
        System.out.println("Executing..");
    }
    @Test void testExecute() {
        execute();
    }
}

被注解的方法与其他方法没有区别。在这个例子中,注解@Test可以与任何修饰符共同作用与方法,例如public、static或void。从语法的角度来看,注解的使用方式几乎与修饰符的使用方式一模一样。

1.1定义注解

下面就是前例中用到的注解@Test的定义。可以看到,注解的定义看起来很像接口的定义。事实上,与其他任何Java接口一样,注解也将会编译成class文件。

package net.mindview.atunit;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNRIME)
public @inteface Test{}

除了@符号以外,@Test的定义很像一个空的接口。定义注解时,会需要一些元注解(meta-annotation),如@Target和@Retention。@Target用来定义你的注解将应用于什么地方(例如是一个方法或者一个域)。@Retention用来定义该注解在哪一级别可用,在源代码中、类文件中或者运行时。

在注解中,一般都会包含一些元素以表示某些值。当分析处理注解时,程序或工具可以利用这些值。注解的元素看齐啦就像接口的方法,唯一的区别是你可以为其指定默认值。

没有元素的注解称为标记注解(marker annotation),例如上例中的@Test。

下面是一个简单的注解,我们可以用它来跟踪一个项目中的用例。如果一个方法或一组方法实现了某个用例的需求,那么程序员可以为此方法加上该注解。于是,项目经理通过计算已经实现的用例久可以很好的掌握项目的进展。而如果要更新或修改系统的业务逻辑,则维护该项目的开发人员也可以很容易的在代码中找到对应的用例。

//:annotations/UseCase.java
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
    public int id();
    public String description() detault "no description";
}

注意,id和decription类似方法的定义。由于编译器会对id进行类型检查,因此将用力文档的追踪数据库与源代码相关联是可靠的。description元素有一个default值,如果在朱姐某个方法时没有给出description的值,则该朱姐的处理器就会使用此元素的默认值。
在下面的类中,有三个方法被注解为用例:

//:annotations/PasswordUtils.java
import java.util.*;
public class PasswordUtils {
    @UseCase(id = 47, description = "Password must contain at least one numeric")
    public boolean validatePassword(String password) {
        return (password.matchs("\\w*\\d\\w*"));
    }
    @UseCase(id = 47)
    public String encryptPassword(String password) {
        return new StringBuilder(password).reverse().toString();
    }
    @UseCase(id = 49, description = "New Passwords can't equal previously used ones")
    public boolean chackForPassword(List<String> prevPasswords, String password) {
        return !prevPasswords.contains(password);
    }
}

注解的元素在使用时表现为名-值对的形式,并需要置于@UseCase声明之后的括号内。在encryptPassword()方法的注解中,并没有给出description元素的值,因此,在UseCase的注解处理器分析处理这个类时会使用钙元素的默认值。

1.2 元注解

Java目前只内置了三种标准注解(前面介绍过),以及四种元注解。元注解专职负责注解其他的注解:

@Target

表示该注解可以用于什么地方。可能的ElementType参数包括:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、借口(包括注解类型)或enum声明

@Retention

表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃。
CLASS:注解在class文件中可用,但会被VM丢弃。
RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息。

@Documented

将此注解包含在Javadoc中。

@Inherited

允许子类继承父类中的注解。

大多数时候,程序员主要是定义自己的注解,并编写自己的处理器来处理他们。

待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值