Java-了解注解及其应用

标签: java 注解 应用 | 发表时间:2014-03-28 03:17 | 作者:顺其自然EVO
出处:http://www.blogjava.net/qileilove/
一、注解基本了解和应用
  1、何为注解?
  注解就是一种标记,在程序中加了注解就等于加了标记,没加,就没有标记。
  2、注解有何作用?
  加了注解, java编译器、开发工具或是其他程序可以通过反射技术了解你的类或各种元素是否有标记,有什么标记就做什么
  样的事情。比如:子类重写父类的方法,方法上必须有@override标记;若一个方法已过时不用了,就该方法添加注
  解@Deprecated,调用者反射时就明白这方法已过时
  3、注解在哪标记,也就是说能为哪些元素标记?
  可以在包、类、字段、方法、局部变量
   二、自定义注解及其应用
  1、先定义个注解类,如下代码:
/**
* 自定义注解类
* @author Administrator
*
*/
public @interface AnimTest {
}
   2、将这个注解类应用到某个类上,然后用反射查看判断该类是否被这个注解类所标记
package com.itcast.test;
import com.itcast.zhujie.AnimTest;
@AnimTest   //这是自定义的注解
public class ZhujieTest {
/**
* @param args
*/
public static void main(String[] args) {
boolean isAnim  = ZhujieTest.class.isAnnotationPresent(AnimTest.class);
if(isAnim)
System.out.println("it  has one");
else
System.out.println("no have");
}
}
  输出的结果是:no have ;表示该类没有找到注解标记,这是为何呢?不是在类上已经使用了注解了嘛?
  回答这问题之前,我们先 学习一个东西,Retention元注释类,指的是注释类型的注释要留多久。如果某个注释类型没有声明Retention元注释,则保留策略为默认的RetentionPolicy.CLASS,表示保留到编译时,运行时就会被剔除。  RetentionPolicy 是一个枚举类型,有三个值:SOURCE、CLASS 、  RUNTIME 分别对应着Java源文件、class文件、内存中的字节码
  我们在重新看下上个代码,AnimTest 没有声明Retention,故保留默认的CLASS,只保留到编译时期。所以内存中加载类文件时,注解类已被清除,所以才会找不到AnimTest注解类的标记。要想在反射中能找到该标记,只要设置下注解类的保留周期,所以接着改下这个注解类
/**
* 自定义注解类
* @author Administrator
*
*/
@Retention(value = RetentionPolicy.RUNTIME)     //表示运行时也保留该注解类
public @interface AnimTest {
}
  在执行代码,结果是:it  has  one
  3、现在有个问题,就是注解类的使用范围是怎样的呢?只能在类上么?
  其实有个元注释Tagert来限定范围的。Tagert 指的是注释类型所适用的程序元素的种类。如果注释类没有声明Tagert元注释,则可以适用于任何元素上,如果声明了,编译器就会强制实施指定的范围
  如果要使AnimTest只作用于方法上,则在注释类声明Tagert
/**
* 自定义注解类
* @author Administrator
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD})    //限定范围,作用于方法
public @interface AnimTest {
}
  那么这个注解类就不能作用于类上了,否则会编译异常,只能作用于方法上,代码如下:
public class ZhujieTest {
/**
* @param args
*/
@AnimTest  //作用于方法上
public static void main(String[] args) {
boolean isAnim  = ZhujieTest.class.isAnnotationPresent(AnimTest.class);
if(isAnim)
System.out.println("it  has one");
else
System.out.println("no have");
}
}
  如果注释类既可以使用类上也可以作用 于方法上,只要修改为 @Target(value = {ElementType.METHOD,ElementType.TYPE}),type是表示类型
   三、为注解增加各种属性
  1、现在给注解类添加各种属性,类似接口形式,只提供方法
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.itcast.classdemo.WeekDay;
/**
* 自定义注解类
* @author Administrator
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.ANNOTATION_TYPE})
public @interface AnimTest {
String color();   //字符串
int count();    //整型
int[] arr();   //数组
MetaAnnotation meta() default @MetaAnnotation("very food");  //注释类型
WeekDay day() default WeekDay.MON;   //枚举类型
}
//注释类
public @interface MetaAnnotation {
String value() default "heollo";    //提供默认值
}
//枚举类
public enum WeekDay {
SUN,MON
}
  2、以下是测试注释类调用属性
import com.itcast.zhujie.AnimTest;
@AnimTest (color ="red",count =1,arr=234)   //这是自定义的注解,并为其属性赋值
public class ZhujieTest {
/**
* @param args
*/
@AnimTest (color ="blue",count=2,arr={3,21})
public static void main(String[] args) {
//是否含有AnimTest注释标记
boolean isAnim  = ZhujieTest.class.isAnnotationPresent(AnimTest.class);
if(isAnim){
//获取AnimTest注释标记对象
AnimTest an = ZhujieTest.class.getAnnotation(AnimTest.class);
//以下都是获取AnimTest注释标记对象的属性
System.out.println(an.color());  // red
System.out.println(an.count());   //1
System.out.println(Arrays.toString(an.arr()));   //[234]
System.out.println(an.meta().value());   //very good
System.out.println(an.day());            //MON
System.out.println("it  has one");
}else
System.out.println("no have");
}
}
  经上述测试总结:
  1)注释类的属性可以有String、int、数组、枚举和注解
  2)注释类的属性可以设置默认值,如String color() default "red";
  3)在使用注释类时,有属性,但没默认值,这时必须要赋值,否则编译不通                过 @AnimTest (color ="blue",count=2,arr={3,21})
  4)获取类上的注释对象,用反射技术AnimTest an = ZhujieTest.class.getAnnotation(AnimTest.class);
  5)获取注释上的属性,类似调用方法一样,需要带括号;
  6)如果注释类只有一个属性要赋值,且属性名为value,则赋值时属性名和等号都可以省略,如:@MetaAnnotation("very food")


顺其自然EVO 2014-03-28 11:17 发表评论

相关 [java 注解 应用] 推荐:

Java-了解注解及其应用

- - BlogJava-qileilove
  注解就是一种标记,在程序中加了注解就等于加了标记,没加,就没有标记. java编译器、开发工具或是其他程序可以通过反射技术了解你的类或各种元素是否有标记,有什么标记就做什么. 比如:子类重写父类的方法,方法上必须有@override标记;若一个方法已过时不用了,就该方法添加注.   解@Deprecated,调用者反射时就明白这方法已过时.

java注解应用实例 - Annotation, 自定义注解, 注解类规则

- - ITeye博客
本文介绍了java的自定义注解及注解类编写的规则, 并通过实例来说明下如何使用java的注解. 实例演示了注解在类,构造方法,方法和字段的使用. 可以从这里下载到完成的工程代码: http://dl.iteye.com/topics/download/f74972df-234f-30c9-aadd-ca2ed1376bc2.

Java应用运维

- - BlueDavy之技术blog
对于互联网产品或长期运行的产品而言,运维工作非常重要,尤其是在产品复杂了以后,在这篇blog中就来说下Java应用的运维工作(ps:虽然看起来各种语言做的系统的运维工作都差不多,但细节上还是会有很多不同,so本文还是只讲Java的). 苦逼的码农按照需求开发好了一个全新的Java Web应用,该发布上线给用户用了,要把一个Java Web应用发布上线,首先需要搭建运行的环境,运行的环境需要有JDK、APPServer,在已经装好了os的机器上装上JDK和APPServer,开发好的Java Web应用可以用maven直接打成war或ear,将这个打好的包scp或其他方式到目标机器上,准备妥当,就差启动了.

Java线程池应用

- - CSDN博客架构设计推荐文章
1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务. 2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机). Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.

Java 应用一般架构

- - SegmentFault 最新的文章
原文地址: https://blog.coding.net/blog/General-architecture-for-Java-applications. 当我们架设一个系统的时候通常需要考虑到如何与其他系统交互,所以我们首先需要知道各种系统之间是如何交互的,使用何种技术实现. 现在我们常见的不同系统不同语言之间的交互使用WebService,Http请求.

使用Java注解进行Spring bean管理

- - 编程语言 - ITeye博客
原文链接: http://www.ibm.com/developerworks/cn/webservices/ws-springjava/. 使用 Java 配置进行 Spring bean 管理. 学习使用 Java 配置管理 Spring bean. Spring bean 是使用传统的 XML 方法配置的.

使用AOP与注解记录Java日志

- - ImportNew
有些时候,我想要把每个运行过的方法接收到的参数、返回值和执行时间等信息记录(通过slf4j 和 log4j)下来. 在AspectJ、jcabi-aspects和Java注解的帮助下我实现了这个想法. 在log4j中可以看到以下输出:. 接下来我们来看看它是如何工作的. 注解是Java 6中采用的一种技术( 译注:其实Java 5就有注解了).

xssProject在java web项目中应用

- - Java - 编程语言 - ITeye博客
1.项目引入xssProtect-0.1.jar、antlr-3.0.1.jar、antlr-runtime-3.0.1.jar包. * 覆盖getParameter方法,将参数名和参数值都做xss过滤. * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取
.

使用Gradle构建Java Web应用(译)

- - BlogJava-首页技术区
使用Gradle构建Java Web应用. 本文是发布在 java.net上的一篇摘自于一书中的 节选,介绍了使用 Gradle构建Java Web应用的过程. 刚刚接触Gradle,看到了这篇小文,随手译了出来:-) (2014.01.23最后更新). 在职业生涯和私人生活中,我们中间的许多人要同时管理多个项目.

消除Java应用中的Exception开销

- - 舒の随想日记
抛异常最大的消耗在于构造整个异常栈的过程,如果你的栈很深,特别是用了一些框架的话,这个开销基本是不可忽视的,之前做的一个优化显示当时应用中的一个异常使得整个应用的性能下降至少30%. 最大开销的地方在这里,当你去new一个Exception的时候,会调用父类Throwable的构造函数, Throwable的构造函数中会调用native的fillInStackTrace(),这个方法就会构造整个异常栈了.