概念

Annontation是Java5开始引入的新特征。中文名称一般叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据与程序元素(类、方法、成员变量等)进行关联。更通俗的意思是为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且是供指定的工具或框架使用的。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。

Annotation为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻方便地使用这些数据(通过解析注解来使用这些数据)常见的作用有以下几种:

  • 生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等
  • 跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。也是
  • 在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。

原理

  Annotation其实是一种接口。通过Java的反射机制相关的API来访问annotation信息。相关类(框架或工具中的类)根据这些信息来决定如何使用该程序元素或改变它们的行为。

java提供的几个基本注解

在jdk1.5的java.lang包中预定义了三个注解。分别是Override、Deprecated和SuppressWarnings。

Override

表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。这个注解的作用是标识某一个方法是否覆盖了它的父类的方法,常常在我们试图覆盖父类方法却又写错了方法名时提供了一个保障性的校验过程。

Deprecated

用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。

SuppressWarnings

指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。

此注解能告诉Java编译器关闭对类、方法及成员变量的警告。有时编译时会提出一些警告,对于这些警告有的隐藏着Bug,有的是无法避免的,对于某些不想看到的警告信息,可以通过这个注解来屏蔽。

例如

 import java.util.*;
public class AnnotationTest { public static void main(String[] args) { List li =new ArrayList();
li.add("abc");
}
}

这个类编译的时候会出现如下警告:

注: AnnotationTest.java使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。

要解决这个问题:

1.可以为List集合加上泛型限定元素类型

2.可以在第三行代码处加上@SuppressWarnings (value={"unchecked"})

java中的元注解

Rentention

注解的生命周期:Java源文件—》class文件—》内存中的字节码。编译或者运行时,都有可能会取消注解。
默认值是枚举RententionPolicy的3种取值意味让注解保留到哪个阶段:

RententionPolicy.SOURCE的作用是不将注解保存在class文件中,也就是说象“//”一样在编译时被过滤掉了。

RententionPolicy.CLASS(默认值)的作用是只将注解保存在class文件中,而使用反射读取注解时忽略这些注解。

RententionPolicy.RUNTIME的作用是即将注解保存在class文件中,可以通过反射读取注解。

@Override、@SuppressWarnings是默认保留到SOURCE阶段;@Deprecated是保留到RUNTIME阶段。

总的说,Rentention相当于注解类的一个属性,因为Rentention的值不同,注解类保留到的阶段不同。

Target 

指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。通俗的讲,就是注释应用在哪个目标上。

取值为枚举ElementType中的值

ANNOTATION_TYPE
注释类型声明
CONSTRUCTOR

构造方法声明
FIELD

字段声明(包括枚举常量)
LOCAL_VARIABLE

局部变量声明
METHOD

方法声明
PACKAGE

包声明
PARAMETER

参数声明
TYPE

类、接口(包括注释类型)或枚举声明

Documented

指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented 来注释的,则其注释将成为注释元素的公共 API 的一部分。在默认的情况下在使用javadoc自动生成文档时,注解将被忽略掉。如果想在文档中也包含注解,必须使用Documented为文档注解。

Inherited

在默认的情况下,父类的注解并不会被子类继承。如果要继承,就必须加上Inherited注解。

为注解增加高级属性

数组类型的属性
int [] arrayAttr() default {1,2,3};
@MyAnnotation(arrayAttr={2,3,4})
如果数组属性中只有一个元素,这时候属性值部分可以省略大括
枚举类型的属性
EnumTest.TrafficLamp lamp() ;
@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)
注解类型的属性:
MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");
@MyAnnotation(annotationAttr=@MetaAnnotation(“yyy”) )

自定义注解

需求:

(1)定义两个自定义注解类,要求可以使用简写方式为属性赋值。

1.定义作者信息,name,group和value,注解的属性类型为String,int,并且可以被保留到程序运行时,使其注解在方法上;

2.定义版本信息edition,注解的属性类型为double,并且可以被保留到程序运行时,使其注解在类上。

(2)定义一个类MyClass,要求有三个方法method1、2、3

使用(1)中的注解1来注释method1,2,3,并对属性参数分别赋值。其中method3使用缺省赋值。

(3)定义一个测试类,要求使用反射来测试MyClass中所有的被注解的方法。

 import java.lang.annotation.*;
/**
定义作者信息,name,group,value
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Author {
String name()default "XXX";
int value()default 8888;
String group()default "other";
}
 import java.lang.annotation.*;
/**
定义版本信息 edition
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Edition {
double value();
}
 @Edition(1.0)
public class MyClass { @Author(name = "zhangsan",group="com.itheima",value=123)
public void method1(){} @Author(name = "wangwu",group="com.itheima",value=456)
public void method2(){} @Author
public void method3(){} }
 import java.lang.reflect.Method;
public class AnnotationTest {
/**
在运行时通过反射分析处理annotation类型的信息
*/
public static void main(String[] args) {
try {
System.out.println("版本信息:");
if(MyClass.class.isAnnotationPresent(Edition.class))
{ //用反射方式获得注解对应的实例对象
Edition edition = (Edition)MyClass.class.getAnnotation(Edition.class);
//通过该对象调用属性对应的方法
System.out.println(edition.value());
}
System.out.println("作者信息:");
Method[] methods = MyClass.class.getMethods();
for (Method method : methods) {
if(method.isAnnotationPresent(Author.class))
{
Author author = (Author)method.getAnnotation(Author.class);
System.out.println(author.name()+"\t"+author.group()+"\tID"+author.value());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
---------- 运行 ----------
版本信息:
1.0
作者信息:
zhangsan com.itheima ID123
wangwu com.itheima ID456
XXX other ID8888 输出完成 (耗时 0 秒) - 正常终止

java-注解的更多相关文章

  1. Java注解

    Java注解其实是代码里的特殊标记,使用其他工具可以对其进行处理.注解是一种元数据,起到了描述.配置的作用,生成文档,所有的注解都隐式地扩展自java.lang.annotation.Annotati ...

  2. 19.Java 注解

    19.Java注解 1.Java内置注解----注解代码 @Deprecated                                    //不推荐使用的过时方法 @Deprecated ...

  3. Java注解入门

    注解的分类   按运行机制分:   源码注解:只在源码中存在,编译后不存在 编译时注解:源码和编译后的class文件都存在(如@Override,@Deprecated,@SuppressWarnin ...

  4. java注解(Annotation)解析

    注解(Annotation)在java中应用非常广泛.它既能帮助我们在编码中减少错误,(比如最常见的Override注解),还可以帮助我们减少各种xml文件的配置,比如定义AOP切面用@AspectJ ...

  5. JAVA 注解的几大作用及使用方法详解

    JAVA 注解的几大作用及使用方法详解 (2013-01-22 15:13:04) 转载▼ 标签: java 注解 杂谈 分类: Java java 注解,从名字上看是注释,解释.但功能却不仅仅是注释 ...

  6. attilax.java 注解的本质and 使用最佳实践(3)O7

    attilax.java 注解的本质and 使用最佳实践(3)O7 1. 定义pojo 1 2. 建立注解By eclipse tps 1 3. 注解参数的可支持数据类型: 2 4. 注解处理器 2 ...

  7. paip.java 注解的详细使用代码

    paip.java 注解的详细使用代码 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/att ...

  8. JAVA 注解的几大作用及使用方法详解【转】

    java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解 ...

  9. 框架基础——全面解析Java注解

    为什么学习注解? 学习注解有什么好处? 学完能做什么? 答:1. 能够读懂别人写的代码,特别是框架相关的代码: 2. 让编程更加简洁,代码更加清晰: 3. 让别人高看一眼. spring.mybati ...

  10. Java注解配置

    Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用.包含在 java.lang.annota ...

随机推荐

  1. 关于apache httpd.conf脚本的理解

    新人一枚,这两天一直在研究lamp的搭建,感觉自己对apache理解的不够深彻,决定写这一篇(翻译)httpd.conf文件 未完待续 cat /usr/local/apache/conf/httpd ...

  2. JAVA 中数据库连接的方法之一

    /** * 数据库连接类 * */ package com.cn.MysqlConnect; import java.sql.Connection;import java.sql.DriverMana ...

  3. c程序中出现segment error 和 bus error 的原因

    在c程序中,经常会遇到段错误(segment error)和总线错误(bus error),这两种问题出现的原因可能如下 段错误: 对一个NULL指针解引用. 访问程序进程以外的内存空间. 实际上,第 ...

  4. [题解]vijos 运输计划

    Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...

  5. Windows XP SP3下成功编译CUint2.1-3

    软件环境:Visual C++ 6.0 操作系统:Windows XP SP3 从sourceforge.net下载CUint-2.1-3.tar.bz解压出目录CUnit-2.1-3 从CUint打 ...

  6. Python模块:struct

    各个编程语言都有自己的数据类型,当python需要接受其他语言或者网络传输来交互数据的时候,需要考虑到python的数据类型与其他平台之间交互问题.而python的struct就是解决这个问题的. s ...

  7. 四元数(Quaternions)简介

    经常在代码中看到Quaternions,也知道它是用来表达三维空间的旋转的,但一直没有更深的理解.这两天终于花点时间看了看维基百科的介绍,算是多了解了点.做个记录吧! 本质上而言,四元数是一个数学概念 ...

  8. 调用 WebService 浏览器提示 500 (Internal Server Error) 的原因及解决办法

    在 ASP.NET 开发中,WebService部署成站点之后,如果在本地测试WebService可以运行,在远程却显示“测试窗体只能用于来自本地计算机的请求”或 者"The test fo ...

  9. win2008 IIS与php整合

    首先安装好IIS 安装的时候 要注意三个地方打得勾 注:   CGI  会在IIS+PHP的环境中用到 php.ini default_socket_timeout = 60extension_dir ...

  10. 影响google PageRank的因素

    1 与pr高的网站做链接: 2 内容质量高的网站链接 3 加入搜索引擎分类目录 4 加入免费开源目录 5 你的链接出现在流量大.知名度高.频繁更新的重要网站上 6 google对PDF格式的文件比较看 ...