深入理解Java:注解(Annotation)自己定义注解入门

要深入学习注解。我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前。我们就必须要了解Java为我们提供的元注解和相关定义注解的语法。

元注解:

元注解的作用就是负责注解其它注解。

Java5.0定义了4个标准的meta-annotation类型。它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
    1.@Target,
    2.@Retention,
    3.@Documented,
    4.@Inherited
  这些类型和它们所支持的类在java.lang.annotation包中能够找到。以下我们看一下每一个元注解的作用和对应分參数的使用说明。


  @Target:

   @Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法參数和本地变量(如循环变量、catch參数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。

  作用:用于描写叙述注解的使用范围(即:被描写叙述的注解能够用在什么地方)

  取值(ElementType)有:

    1.CONSTRUCTOR:用于描写叙述构造器
    2.FIELD:用于描写叙述域
    3.LOCAL_VARIABLE:用于描写叙述局部变量
    4.METHOD:用于描写叙述方法
    5.PACKAGE:用于描写叙述包
    6.PARAMETER:用于描写叙述參数
    7.TYPE:用于描写叙述类、接口(包含注解类型) 或enum声明

  使用实例:  

@Target(ElementType.TYPE)
public @interface Table {
/**
* 数据表名称注解,默认值为类名称
* @return
*/
public String tableName() default "className";
} @Target(ElementType.FIELD)
public @interface NoDBColumn { }

  注解Table 能够用于注解类、接口(包含注解类型) 或enum声明,而注解NoDBColumn仅可用于注解类的成员变量。


  @Retention:

  @Retention定义了该Annotation被保留的时间长短:某些Annotation仅出如今源码中。而被编译器丢弃。而还有一些却被编译在class文件里;编译在class文件里的Annotation可能会被虚拟机忽略,而还有一些在class被装载时将被读取(请注意并不影响class的执行,由于Annotation与class在使用上是被分离的)。使用这个meta-Annotation能够对 Annotation的“生命周期”限制。

  作用:表示须要在什么级别保存该凝视信息,用于描写叙述注解的生命周期(即:被描写叙述的注解在什么范围内有效)

  取值(RetentionPoicy)有:

    1.SOURCE:在源文件里有效(即源文件保留)
    2.CLASS:在class文件里有效(即class保留)
    3.RUNTIME:在执行时有效(即执行时保留)

  Retention meta-annotation类型有唯一的value作为成员。它的取值来自java.lang.annotation.RetentionPolicy的枚举类型值。

详细实比例如以下:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
public String name() default "fieldName";
public String setFuncName() default "setField";
public String getFuncName() default "getField";
public boolean defaultDBValue() default false;
}

  Column注解的的RetentionPolicy的属性值是RUTIME,这样注解处理器能够通过反射,获取到该注解的属性值。从而去做一些执行时的逻辑处理


  @Documented:

  @Documented用于描写叙述其它类型的annotation应该被作为被标注的程序成员的公共API。因此能够被比如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
public String name() default "fieldName";
public String setFuncName() default "setField";
public String getFuncName() default "getField";
public boolean defaultDBValue() default false;
}

  @Inherited:

  @Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。假设一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

  注意:@Inherited annotation类型是被标注过的class的子类所继承。

类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。

  当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这样的继承性。

假设我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现。或者到达类继承结构的顶层。

  实例代码:

/**
*
* @author peida
*
*/
@Inherited
public @interface Greeting {
public enum FontColor{ BULE,RED,GREEN};
String name();
FontColor fontColor() default FontColor.GREEN;
}

自己定义注解:

  使用@interface自己定义注解时,自己主动继承了java.lang.annotation.Annotation接口。由编译程序自己主动完毕其它细节。在定义注解时,不能继承其它的注解或接口。@interface用来声明一个注解,当中的每一个方法实际上是声明了一个配置參数。方法的名称就是參数的名称,返回值类型就是參数的类型(返回值类型仅仅能是基本类型、Class、String、enum)。能够通过default来声明參数的默认值。

  定义注解格式:
  public @interface 注解名 {定义体}

  注解參数的可支持数据类型:

    1.全部基本数据类型(int,float,boolean,byte,double,char,long,short)
    2.String类型
    3.Class类型
    4.enum类型
    5.Annotation类型
    6.以上全部类型的数组

  Annotation类型里面的參数该怎么设定:
  第一,仅仅能用public或默认(default)这两个訪问权修饰.比如,String value();这里把方法设为defaul默认类型;   
  第二,參数成员仅仅能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.比如,String value();这里的參数成员就为String;  
  第三,假设仅仅有一个參数成员,最好把參数名称设为”value”,后加小括号.例:以下的样例FruitName注解就仅仅有一个參数成员。

  简单的自己定义注解和使用注解实例:

package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 水果名称注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
String value() default "";
}
package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 水果颜色注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
/**
* 颜色枚举
* @author peida
*
*/
public enum Color{ BULE,RED,GREEN}; /**
* 颜色属性
* @return
*/
Color fruitColor() default Color.GREEN; }
package annotation;

import annotation.FruitColor.Color;

public class Apple {

    @FruitName("Apple")
private String appleName; @FruitColor(fruitColor=Color.RED)
private String appleColor; public void setAppleColor(String appleColor) {
this.appleColor = appleColor;
}
public String getAppleColor() {
return appleColor;
} public void setAppleName(String appleName) {
this.appleName = appleName;
}
public String getAppleName() {
return appleName;
} public void displayName(){
System.out.println("水果的名字是:苹果");
}
}

注解元素的默认值:

  注解元素必须有确定的值。要么在定义注解的默认值中指定,要么在使用注解时指定。非基本类型的注解元素的值不可为null。因此, 使用空字符串或0作为默认值是一种经常使用的做法。这个约束使得处理器非常难表现一个元素的存在或缺失的状态。由于每一个注解的声明中,全部元素都存在,而且都具有对应的值,为了绕开这个约束。我们仅仅能定义一些特殊的值。比如空字符串或者负数。一次表示某个元素不存在,在定义注解时,这已经成为一个习惯使用方法。

比如:

 1 package annotation;
2
3 import java.lang.annotation.Documented;
4 import java.lang.annotation.ElementType;
5 import java.lang.annotation.Retention;
6 import java.lang.annotation.RetentionPolicy;
7 import java.lang.annotation.Target;
8
9 /**
10 * 水果供应者注解
11 * @author peida
12 *
13 */
14 @Target(ElementType.FIELD)
15 @Retention(RetentionPolicy.RUNTIME)
16 @Documented
17 public @interface FruitProvider {
18 /**
19 * 供应商编号
20 * @return
21 */
22 public int id() default -1;
23
24 /**
25 * 供应商名称
26 * @return
27 */
28 public String name() default "";
29
30 /**
31 * 供应商地址
32 * @return
33 */
34 public String address() default "";
35 }

  定义了注解。并在须要的时候给相关类,类属性加上注解信息,假设没有响应的注解信息处理流程。注解能够说是没有有用价值。

怎样让注解真真的发挥作用。主要就在于注解处理方法。下一步我们将学习注解信息的获取和处理!

深入理解Java:注解(Annotation)自己定义注解入门的更多相关文章

  1. Java中注解Annotation的定义、使用、解析

    此例子,用于说明如何在Java中对“注解 Annotation”的定义.使用和解析的操作.注解一般用于自定义开发框架中,至于为什么使用,此处不作过多说明,这里只说明如何使用,以作备记.下面例子已测试, ...

  2. 深入JAVA注解(Annotation):自定义注解 (转)

    原文出自:http://blog.csdn.net/yjclsx/article/details/52101922 一.基础知识:元注解 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义 ...

  3. Java注解Annotation与自定义注解详解

    Java注解简介 开发中经常使用到注解,在项目中也偶尔会见到过自定义注解,今天就来探讨一下这个注解是什么鬼,以及注解的应用场景和如何自定义注解. 下面列举开发中常见的注解 @Override:用于标识 ...

  4. Java注解与自己定义注解处理器

    动机 近期在看ButterKnife源代码的时候.竟然发现有一个类叫做AbstractProcessor,并且ButterKnife的View绑定不是依靠反射来实现的,而是使用了编译时的注解,自己主动 ...

  5. java 编程基础:注解(Annotation Processing Tool)注解处理器 利用注解解读类属性生成XML文件

    APT的介绍: APT(Annotation Processing Tool)是一种注解处理工具,它对源代码文件进行检测,并找出源文件所包含的注解信息,然后针对注解信息进行额外的处理. 使用APT工具 ...

  6. Annotation(jdk5.0注解)复习(转自http://3w_cnblogs_com/pepcod/)

    package annotation.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retent ...

  7. [2]注解(Annotation)-- 深入理解Java:注解(Annotation)自定义注解入门

    转载 http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 深入理解Java:注解(Annotation)自定义注解入门 要深入学习 ...

  8. 深入理解Java注解类型(@Annotation)

    http://blog.csdn.net/javazejian/article/details/71860633  出自[zejian的博客] java注解是在JDK5时引入的新特性,鉴于目前大部分框 ...

  9. 深入理解Java的注解(Annotation):自定义注解入门(2)

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...

随机推荐

  1. Codevs 数字三角形 问题合集

    1220 数字三角形 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 如图所示的数字三角形,从顶部出发,在每一结点可以选择向左走或得 ...

  2. hdu 5455(字符串处理)

    Fang Fang Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total S ...

  3. ASP.NET Core 中间件基本用法

    ASP.NET Core 中间件 ASP.NET Core的处理流程是一个管道,而中间件是装配到管道中的用于处理请求和响应的组件.中间件按照装配的先后顺序执行,并决定是否进入下一个组件.中间件管道的处 ...

  4. systemtap-oracle

    https://savvinov.com/2015/12/21/non-intrusive-tracing/ https://mahmoudhatem.wordpress.com/2016/01/11 ...

  5. SQL-基础学习3--通配符:LIKE,%,(_); 拼接:+,||,concat;

    第六课 用通配符进行过滤 6.1  LIKE操作符 通配符本身实际上是SQL的WHERE子句中有特殊含义的字符,SQL支持几种通配符.为在搜索子句中使用通配符,必须使用LIKE操作符.LIKE指示DB ...

  6. andriod Java中度转度分秒

    public String trandu2m(double d) { //gisoracle 编号 try { //double dd = Convert.ToDouble(str); String ...

  7. iOS -- xxxViewController进行pop时直接crash进main.m,EXC_BAD_ACCESS(code=1,address=0x20)

    今天在调试程序时,遇到了奇怪的错误.我从主页跳进(push)一个ViewController时一切正常,但是返回主页(pop)时却crash了,直接跳进了main.m(EXC_BAD_ACCESS(c ...

  8. 调用tensorflow中的concat方法时Expected int32, got list containing Tensors of type '_Message' instead.

    grid = tf.concat(0, [x_t_flat, y_t_flat, ones])#报错语句 grid = tf.concat( [x_t_flat, y_t_flat, ones],0) ...

  9. DAO 层实现

    一.实验介绍 1.1 实验内容 本节课程主要利用 MyBatis 框架实现 DAO 层. 1.2 实验知识点 MyBatis 框架 MySQL 1.3 实验环境 JDK1.8 Eclipse Java ...

  10. Why is chkconfig no longer available in Ubuntu?

    Question: I can not use chkconfig tools in Ubuntu 12.10 It's a very useful tools to configure the se ...