注解(也被称作元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们在稍后某个时刻可以很方便的使用这些数据,其在一定程度上将元数据与源代码文件结合在一起,而不是保存在外部文档中。

注解使我们可以用将来由编译器测试和验证的格式,存储程序有关的额外信息。注解可以用来生成描述符文件,甚至是新的类定义,并且有助于减轻编写“样板”代码的负担。通过使用注解,将元数据保存在Java源代码中,并利用annotation API为注解构造处理工具来读取注解。

Java目前只内置了三种标准注解,以及四种元注解。元注解专职负责注解其他注解。大多数时候,程序员都是定义自己的注解,并编写自己的注解处理器来处理他们。

一个简单的注解例子

注解定义:

 import java.lang.annotation.*;

 @Target(ElementType.METHOD)                    //定义注解用于什么地方
@Retention(RetentionPolicy.RUNTIME) //定义注解在哪个级别可用
public @interface UseCase {
public int id();
public String description() default "no description";
}

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

使用注解:

 import java.util.*;

 public class PasswordUtils {
@UseCase(id = 47, description = "Password must contain at least one numeric")
public boolean validataPassword(String password) {
return (password.matches("\\w*\\d\\w*"));
} @UseCase(id = 48)
public String encryptPassword(String password) {
return new StringBuilder(password).reverse().toString();
} @UseCase(id = 49, description = "New password can't equal previously used ones")
public boolean checkForNewPassword(List<String> prevPasswords, String password) {
return !prevPasswords.contains(password);
}
}

注解@UseCase可以与任何修饰符共同作用于方法,例如public、static或void。从语法角度看,注解的使用方式几乎与修饰符的使用一模一样。注解的定义很像接口的定义,注解与其他任何Java接口一样,会被编译成class文件。

编写注解处理器:

 import java.lang.reflect.*;
import java.util.*; public class UseCaseTracker {
public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
for (Method m : cl.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if (uc != null) {
System.out.println("Found Use Case:" + uc.id() + " " + uc.description());
useCases.remove(new Integer(uc.id()));
}
}
for (int i : useCases) {
System.out.println("Warning:Missing use case-" + i);
}
}
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases, 47, 48, 49, 50);
trackUseCases(useCases, PasswordUtils.class);
}
}

如果没有用来读取注解的工具,那注解不会比注释更有用。使用注解的过程中,很重要的一个部分就是创建与使用注解处理器。Java SE5扩展了反射机制的API,以帮助程序员构造这类工具。同时,它还提供一个外部工具apt帮助程序员解析带有注解的Java源代码。

注解元素的类型:

· 所有基本类型(int, float, boolean等)

· String

· Class

· enum

· Annotation

· 以上类型的数组

如果是使用了其他类型,编译器会报错。注解也可以作为元素的类型,即注解可以嵌套。

参考:《Java编程思想》

Java注解简单学习的更多相关文章

  1. Java注解系统学习与实战

    背景 为什么要再次梳理一下java注解,显而易见,因为重要啊.也是为研究各大类开源框架做铺垫,只有弄清楚Java注解相关原理,才能看懂大部分框架底层的设计. 缘起 注解也叫做元数据,是JDK1.5版本 ...

  2. 【Java基础】Java注解简单入门

    注解简单来说就是配置,是特别的配置,之前常用的配置文件,可以用注解替换.然后通过反射去获取注解的信息. 如何定义一个注解 你在IDE中新建一个注解定义,是这样的结构的: package com.nic ...

  3. java注解简单使用

    java注解可以比喻成标签,可以贴在任何地方,也可以限制只能贴在固定地方,比如类上方.方法上方.属性[字段]上方等,然后通过反射,判断是否存在这个注解. 注解形式 public @interface ...

  4. Java注解Annotation学习

    学习注解Annotation的原理,这篇讲的不错:http://blog.csdn.net/lylwo317/article/details/52163304 先自定义一个运行时注解 @Target( ...

  5. java clone简单学习

    最近在帮忙写单侧的时候,经常会和这几个对象类打交道,因为对java也不是很熟悉,刚好学习一下,都是很浅的学习,并没有深入的去学习哈,因为感觉也用不上. protected Object clone() ...

  6. Java注解Annotation学习笔记

    一.自定义注解 1. 使用关键字 @interface 2. 默认情况下,注解可以修饰 类.方法.接口等. 3. 如下为一个基本的注解例子: //注解中的成员变量非常像定义接口 public @int ...

  7. Java 注解(Annoation)学习笔记

    1 Junit中的@Test为例: 1.1 用注解(@Test)前 private boolean isTestMethod(Method m) { return m.getParameterType ...

  8. java泛型简单学习

    一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: //import java.util.List; public class GenericTest { public st ...

  9. Java抽象类简单学习

    使用抽象类应该注意的几个要点: 包含一个或者多个抽象方法的类必须被声明为抽象类. 将类声明为抽象类,不一定含有抽象方法. 通常认为,在抽象类中不应该包括具体方法,建议尽量将通用的域和方法放在超类中. ...

随机推荐

  1. Java基础语法09-面向对象下-内部类

    九.内部类 将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类. (1)成员内部类:声明在外部类中方法外 静态成员内部类 非静态成员内部类 (2)局部内部类:声明在外部类的方法 ...

  2. oracle创建索引

    数据库索引是为了提高查询速度的一种数据结构. 索引的创建语句 索引的创建语句非常简单. CREATE INDEX 索引名 ON 表名(列名); 除了单列索引,还可以创建包含多个列的复合索引. CREA ...

  3. Android 开发凉了吗!

    昨天我拿了本<安卓开发大全>的书,把它放进了冰箱,你猜怎么样? 它凉了. 记得2013年的时候,安卓崛起,一夜之间遍地谈论安卓这个奇怪的机器人. 安卓受宠的原因,主要围绕着: 1 应用商城 ...

  4. 部署flas到服务器:No module named flask

    首先,你要先把nginx和uwsgi安装好(个人觉得这搭起来比较舒服),可以通过pip 或者源安装,具体方法在前面我有提到过,好了接下来我就讲讲我的踩坑经历与解决办法. 我先采用的pip  insta ...

  5. strcmp函数和memcmp函数的用法区别及联系

    前言: C语言中有很多东西容易搞混,最近笔者就遇到了一个问题.这里做个记录.就是memcmp和strcmp两者的用法,这里做个对比: 功能对比: A memcmp: 函数原型: int memcmp( ...

  6. Elasticsearch系列---初识Elasticsearch

    Elasticsearch是什么? Elasticsearch简称ES,是一个基于Lucene构建的开源.分布式.Restful接口的全文搜索引擎,还是一个分布式文档数据库.天生就是分布式.高可用.可 ...

  7. CEF编译 执行gn args out\Release_GN_x86异常

    gn args out\Debug_GN_x86 用来配置编译参数,执行gn args out\Release_GN_x86时异常: Toolchain is out of date. Run &qu ...

  8. feign响应Image流对象

    feign面向方法签名的http调用,越来越受欢迎,类型于rpc的thrift,只需要关注方法签名和返回值即可,当然feign响应流对象时,需要我们做一下特殊处理,否则会出现异常.也有一些文章通过重写 ...

  9. 构建Electron的常见问题(Mac)

    背景 起因是产品的需求,需要更换Electron为底层平台,但因为会有不少定制化的功能要实现,必须自己实现此类内容,所以也就导致必须自己编译Electron的源代码. 整个构建过程,看Electron ...

  10. ES6- Class类的使用,声明,继承

    声明一个类 //class 类 class Coder{ // 类中都是方法 函数 //val是name方法的参数 name(val){ console.log(val) //类 return val ...