深入理解Java:注解

图片 2

Annotation是如何被拍卖的

当Java源代码被编写翻译时,编写翻译器的三个插件annotation微处理器则会管理那几个annotation。微型机能够爆发报告音信,恐怕创制附加的Java源文件或能源。借使annotation自己被拉长了RententionPolicy的运营时类,则Java编写翻译器则会将annotation的元数据存储到class文件中。然后,Java虚构机或其余的次序能够寻觅那个元数据并做相应的拍卖。

自然除了annotation微机能够管理annotation外,大家也能够动用反射本人来管理annotation。Java
SE
5有一个名字为AnnotatedElement的接口,Java的反射对象类Class,Constructor,Field,Method以致Package都贯彻了那几个接口。那么些接口用来表示最近运转在Java虚构机中的被增添了annotation的主次成分。通过那些接口能够运用反射读取annotation。AnnotatedElement接口能够访谈被加上RUNTIME标识的annotation,相应的办法有getAnnotation,getAnnotations,isAnnotationPresent。由于Annotation类型被编写翻译和积存在二进制文件中就好像class相通,所以能够像查询普通的Java对象同样查询这几个主意再次来到的Annotation。

java.lang.reflect
包下重要富含部分实现行反革命射作用的工具类,实际上,java.lang.reflect
包全部提供的反射API增加了读取运转时Annotation新闻的技艺。当二个Annotation类型被定义为运维时的Annotation后,该注解工夫是运行时可以预知,当class文件棉被服装载时被保存在class文件中的Annotation才会被虚构机读取。
AnnotatedElement
接口是具有程序成分(Class、Method和Constructor)的父接口,所以程序通过反射获取了有些类的AnnotatedElement对象之后,程序就足以调用该目的的如下四个个方式来访谈Annotation消息:

批注微机类库(java.lang.reflect.AnnotatedElement卡塔尔国:

  Java使用Annotation接口来代表前后相继成分前面包车型大巴声明,该接口是颇负Annotation类型的父接口。除此而外,Java在java.lang.reflect
包下新添了AnnotatedElement接口,该接口代表前后相继中能够选用表明的顺序成分,该接口首要犹如下多少个完成类:

  Class:类定义
  Constructor:布局器定义
  Field:累的分子变量定义
  Method:类的方法定义
  Package:类的包定义

  java.lang.reflect
包下主要包蕴部分贯彻反射作用的工具类,实际上,java.lang.reflect
包全部提供的反射API扩张了读取运转时Annotation消息的力量。当三个Annotation类型被定义为运维时的Annotation后,该注脚才具是运作时可以预知,当class文件棉被服装载时被保留在class文件中的Annotation才会被设想机读取。
  AnnotatedElement
接口是兼具程序成分(Class、Method和Constructor)的父接口,所以程序通过反射获取了有些类的AnnotatedElement对象之后,程序就足以调用该对象的如下八个个法子来拜候Annotation新闻:

  方法1:<T extends Annotation> T
getAnnotation(Class<T> annotationClass卡塔尔:
重返改程序成分上存在的、内定项指标注明,假若该类型评释不设有,则赶回null。
  方法2:Annotation[]
getAnnotations(卡塔尔:再次来到该程序成分上设有的有所注解。
  方法3:boolean is AnnotationPresent(Class<?extends Annotation>
annotationClass卡塔尔国:判定该程序成分上是或不是带有内定项目标讲授,存在则赶回true,不然重回false.
  方法4:Annotation[]
getDeclaredAnnotations(卡塔尔(قطر‎:重回直接存在于此成分上的有着注释。与此接口中的其余艺术分化,该措施将忽略世袭的笺注。(如果未有注释直接存在于此成分上,则赶回长度为零的二个数组。)该办法的调用者能够随意退换重返的数组;那不会对另向外调拨运输用者重临的数组暴发别的影响。

  一个简易的注释微处理机:

  1 /***********注解声明***************/
  2 
  3 /**
  4  * 水果名称注解
  5  * @author peida
  6  *
  7  */
  8 @Target(ElementType.FIELD)
  9 @Retention(RetentionPolicy.RUNTIME)
 10 @Documented
 11 public @interface FruitName {
 12     String value() default "";
 13 }
 14 
 15 /**
 16  * 水果颜色注解
 17  * @author peida
 18  *
 19  */
 20 @Target(ElementType.FIELD)
 21 @Retention(RetentionPolicy.RUNTIME)
 22 @Documented
 23 public @interface FruitColor {
 24     /**
 25      * 颜色枚举
 26      * @author peida
 27      *
 28      */
 29     public enum Color{ BULE,RED,GREEN};
 30 
 31     /**
 32      * 颜色属性
 33      * @return
 34      */
 35     Color fruitColor() default Color.GREEN;
 36 
 37 }
 38 
 39 /**
 40  * 水果供应者注解
 41  * @author peida
 42  *
 43  */
 44 @Target(ElementType.FIELD)
 45 @Retention(RetentionPolicy.RUNTIME)
 46 @Documented
 47 public @interface FruitProvider {
 48     /**
 49      * 供应商编号
 50      * @return
 51      */
 52     public int id() default -1;
 53 
 54     /**
 55      * 供应商名称
 56      * @return
 57      */
 58     public String name() default "";
 59 
 60     /**
 61      * 供应商地址
 62      * @return
 63      */
 64     public String address() default "";
 65 }
 66 
 67 /***********注解使用***************/
 68 
 69 public class Apple {
 70 
 71     @FruitName("Apple")
 72     private String appleName;
 73 
 74     @FruitColor(fruitColor=Color.RED)
 75     private String appleColor;
 76 
 77     @FruitProvider(id=1,name="陕西红富士集团",address="陕西省西安市延安路89号红富士大厦")
 78     private String appleProvider;
 79 
 80     public void setAppleColor(String appleColor) {
 81         this.appleColor = appleColor;
 82     }
 83     public String getAppleColor() {
 84         return appleColor;
 85     }
 86 
 87     public void setAppleName(String appleName) {
 88         this.appleName = appleName;
 89     }
 90     public String getAppleName() {
 91         return appleName;
 92     }
 93 
 94     public void setAppleProvider(String appleProvider) {
 95         this.appleProvider = appleProvider;
 96     }
 97     public String getAppleProvider() {
 98         return appleProvider;
 99     }
100 
101     public void displayName(){
102         System.out.println("水果的名字是:苹果");
103     }
104 }
105 
106 /***********注解处理器***************/
107 
108 public class FruitInfoUtil {
109     public static void getFruitInfo(Class<?> clazz){
110 
111         String strFruitName=" 水果名称:";
112         String strFruitColor=" 水果颜色:";
113         String strFruitProvicer="供应商信息:";
114 
115         Field[] fields = clazz.getDeclaredFields();
116 
117         for(Field field :fields){
118             if(field.isAnnotationPresent(FruitName.class)){
119                 FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
120                 strFruitName=strFruitName+fruitName.value();
121                 System.out.println(strFruitName);
122             }
123             else if(field.isAnnotationPresent(FruitColor.class)){
124                 FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
125                 strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
126                 System.out.println(strFruitColor);
127             }
128             else if(field.isAnnotationPresent(FruitProvider.class)){
129                 FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
130                 strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
131                 System.out.println(strFruitProvicer);
132             }
133         }
134     }
135 }
136 
137 /***********输出结果***************/
138 public class FruitRun {
139 
140     /**
141      * @param args
142      */
143     public static void main(String[] args) {
144 
145         FruitInfoUtil.getFruitInfo(Apple.class);
146 
147     }
148 
149 }
150 
151 ====================================
152  水果名称:Apple
153  水果颜色:RED
154  供应商编号:1 供应商名称:陕西红富士集团 供应商地址:陕西省西安市延安路89号红富士大厦

Java申明的底工知识点(见上边导图)基本都过了贰次,下一篇大家透过统筹叁个依照声明的简约的ORM框架,来综合接收和更压实化对声明的依次知识点的理解和应用。

图片 1

 

 

 

参考:

深入明白Java:注脚(Annotation)–表明微机

 

 

 

内容来自:cnblogs:牛奶、不加糖

什么是Annotation?

Annotation翻译为中文即为申明,意思正是提供除了程序本身逻辑外的额外的数量消息。Annotation对于标记的代码未有一向的影响,它不能直接与注脚的代码产生相互影响,但别的零零部件可以选拔那个音讯。

Annotation音讯能够被编写翻译进class文件,也得以保留在Java
虚构机中,进而在运作时能够取得。以至对于Annotation本人也得以加Annotation。

图片 2

_ _
经过整篇的翻阅,相信我们已经能够自定义本人的注释,并落实相应的专门的学业逻辑了。

评释功能:每当你创设描述符性质的类依旧接口时,一旦中间带有重复性的行事,就能够诬捏使用申明来简化与自动化该进程。

Junit

Junit是那叁个有名的一款单元测验框架,使用Junit的时候须要接触大批量的annotation。

  • @Runwith 自定义测验类的Runner
  • @ContextConfiguration 设置Spring的ApplicationContext
  • @DirtiesContext 当实行下叁个测量试验前再一次加载ApplicationContext.
  • @Before 调用测量检验方法前开端化
  • @After 调用测验方法后甩卖
  • @Test 申明该办法是测量检验方法
  • @Ignore 能够加在测验类或测验方法上,忽视运营。
  • @BeforeClass:在该测验类中的全部测量试验方法施行前调用,只被调用一回(被评释的章程必需是static)
  • @AfterClass:在该测量检验类中的全数的测验方法实践完后调用,只被推行一遍(被标记的法子必需是static卡塔尔
/***********注解使用***************/

public class Apple {

    @FruitName("Apple")
    private String appleName;

    @FruitColor(fruitColor=Color.RED)
    private String appleColor;

    @FruitProvider(id=1,name="陕西红富士集团",address="陕西省西安市延安路89号红富士大厦")
    private String appleProvider;

    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 setAppleProvider(String appleProvider) {
        this.appleProvider = appleProvider;
    }
    public String getAppleProvider() {
        return appleProvider;
    }

    public void displayName(){
        System.out.println("水果的名字是:苹果");
    }
}

/***********注解处理器***************/

public class FruitInfoUtil {
    public static void getFruitInfo(Class<?> clazz){

        String strFruitName=" 水果名称:";
        String strFruitColor=" 水果颜色:";
        String strFruitProvicer="供应商信息:";

        Field[] fields = clazz.getDeclaredFields();

        for(Field field :fields){
            if(field.isAnnotationPresent(FruitName.class)){
                FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
                strFruitName=strFruitName+fruitName.value();
                System.out.println(strFruitName);
            }
            else if(field.isAnnotationPresent(FruitColor.class)){
                FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
                strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
                System.out.println(strFruitColor);
            }
            else if(field.isAnnotationPresent(FruitProvider.class)){
                FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
                strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
                System.out.println(strFruitProvicer);
            }
        }
    }
}

/***********输出结果***************/
public class FruitRun {
    /**
     * @param args
     */
    public static void main(String[] args) {
        FruitInfoUtil.getFruitInfo(Apple.class);
    }
}

====================================
 水果名称:Apple
 水果颜色:RED
 供应商编号:1 供应商名称:陕西红富士集团 供应商地址:陕西省西安市延安路89号红富士大厦

@Retention

 @Retention概念了该Annotation被保留的年月长度:有个别Annotation仅出以往源代码中,而被编译器放弃;而另一对却被编写翻译在class文件中;编写翻译在class文件中的Annotation或者会被虚构机忽视,而另一部分在class棉被服装载时将被读取(请小心并不影响class的实践,因为Annotation与class在应用上是被分其余)。使用那么些meta-Annotation能够对
Annotation的“生命周期”约束。

效果与利益:表示需要在怎么等级保存该注释新闻,用于描述注解的生命周期(即:被描述的笺注在什么范围内一蹴而就)

 取值(RetentionPoicy)有:

    1.SOURCE:在源文件中央银立竿见影(即源文件保留)
    2.CLASS:在class文件中央银卓有成效(即class保留)
    3.RUNTIME:在运营时有效(即运营时保留)

应用示例:

  1 /***
  2  * 字段注解接口
  3  */
  4 @Target(value = {ElementType.FIELD})//注解可以被添加在属性上
  5 @Retention(value = RetentionPolicy.RUNTIME)//注解保存在JVM运行时刻,能够在运行时刻通过反射API来获取到注解的信息
  6 public @interface Column {
  7     String name();//注解的name属性
  8 }

 

Column声明的的RetentionPolicy的属性值是RUTIME,这样表明微处理器能够经过反射,获取到该证明的属性值,进而去做一些周转时的逻辑处理

那么些对象能够加Annotation

类,方法,变量,参数,包都能够加Annotation。

转载:
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html

自定义证明

  使用@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(State of Qatar;这里把艺术设为defaul暗中同意类型;   
  第二,参数成员只可以用基本类型byte,short,char,int,long,float,double,boolean各个基本数据类型和
String,Enum,Class,annotations等数据类型,以至这一部分等级次序的数组.举例,String
value(State of Qatar;这里的参数成员就为String;  
  第三,要是唯有叁个参数成员,最佳把参数名称设为”value”,后加小括号.例:下边包车型的士例子FruitName注明就唯有贰个参数成员。

  轻松的自定义注明和平运动用申明实例:

示例1:

  1 /***
  2  *主键注解接口
  3  */
  4 @Target(value = {ElementType.FIELD})
  5 @Retention(value = RetentionPolicy.RUNTIME)
  6 public @interface Id {
  7 }

示例2:

  1 /**属性不需要被持久化注解**/
  2 @Target(value = {ElementType.FIELD})
  3 @Retention(value = RetentionPolicy.RUNTIME)
  4 @Documented
  5 public @interface Transient {
  6 }

能够用与别的annotation上的annotation

@Retention

规定Annotation被封存的生命周期,
要求选择一个Enum对象RetentionPolicy作为参数。

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

@Documented 文档化

@Target

意味着该Annotation能够修饰的限量,选择贰个Enum对象EnumType的数组作为参数。

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE
}

@Inherited

该Annotation能够影响到被声明的类的子类。

六.疏解微处理器

Java提供了多种元注解,专责新表明的创办职业。‘

Spring

Spring 称得上配置地狱,Annotation也不少。

  • @Service 给service类加注明
  • @Repository 给DAO类加申明
  • @Component 给组件类加申明
  • @Autowired 让Spring自动装配bean
  • @Transactional 配置事物
  • @Scope 配置对象共处范围
  • @Controller 给调节器类加注解
  • @RequestMapping url路线映射
  • @帕特hVariable 将艺术参数映射到路线
  • @RequestParam 将诉求参数绑定到艺术变量
  • @ModelAttribute 与model绑定
  • @SessionAttributes 设置到session属性
@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;
}

讲解成分的默许值:

评释成分必需有规定的值,要么在概念注脚的私下认可值中内定,要么在利用表明时钦点,非基本类型的笺注成分的值不得为null。由此,
使用空字符串或0作为暗中认可值是一种常用的做法。这一个限定使得微机很难显现三个因素的存在或缺点和失误的事态,因为各类申明的扬言中,全体因素都设有,并且都怀有相应的值,为了绕开那些约束,大家只好定义一些新鲜的值,比方空字符串只怕负数,一次代表有些成分海市蜃楼,在概念表明时,那早已产生三个习于旧贯用法。

概念了疏解,并在供给的时候给相关类,类性质加上评释音讯,若无响应的笺注消息管理流程,评释能够视为未有实用价值。怎么着让注解真真的发挥功效,首要就在于注明管理措施,下一步大家将学习申明音信的获取和拍卖!

一旦未有用来读取评释的方式和劳作,那么评释也就不会比注释更有用处了。使用注脚的进程中,很要紧的一有的便是创立于选择表明微处理机。Java
SE5扩充了反光机制的API,以救助技师急忙的构造自定义表明微机。

内置的Annotation

@Override 重载父类中方法 @Deprecated 被标注的方式或项目已不再推荐使用

@SuppressWarnings
阻止编写翻译时的告诫音信。其急需摄取二个String的数组作为参数。
可供使用的参数有:

  • unchecked
  • path
  • serial
  • finally
  • fallthrough

一.@Target:
@Target表达了Annotation所修饰的对象限制:Annotation可被用于
packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、结构方法、成员变量、枚举值)、方法参数和本土变量(如循环变量、catch参数)。在Annotation类型的表明中动用了target可进一层明显其修饰的对象。
效益:用于描述阐明的施用约束(即:被描述的解说能够用在哪些地点)
取值(ElementType)有:

@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类型被察觉,或然达到类继承构造的顶层。

JSR 303 – Bean Validation

JSKuga 303 – Bean Validation是二个数据印证的正式,其对Java
bean的求证重要透过Java annotation来贯彻。

  • @Null被讲明的要素必得为 null
  • @NotNull被批注的要素必须不为 null
  • @AssertTrue被疏解的成分必得为 true@AssertFalse被讲授的成分必需为
    false@Min(value卡塔尔国被疏解的因素必得是二个数字,其值必需高于等于钦点的最小值
  • @Max(valueState of Qatar被解说的要素必需是二个数字,其值必需低于等于钦定的最大值
  • @DecimalMin(value卡塔尔(قطر‎被讲明的要素必须是多少个数字,其值必得超越等于钦定的最小值
  • @DecimalMax(value卡塔尔(قطر‎被批注的要素必需是多少个数字,其值必得低于等于钦点的最大值
  • @Size(max, minState of Qatar被解说的要素的轻重必得在钦定的节制内
  • @Digits (integer,
    fraction卡塔尔国被讲授的因素必需是二个数字,其值必需在可肩负的限定内
  • @Past被疏解的要素必需是多个一瞑不视的日子
  • @Future被解说的要素必需是二个现在的日期
  • @Pattern(value卡塔尔国被疏解的成分必得适合内定的正则表明式

事实上还大概有不菲施用了annotaion的framework或library,这里就不一一列举了,希望大家能触类旁通,深切理解Java中的annotation。

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

@Documented

@Documented用于描述其余类型的annotation应该被当做被标记的次序成员的公共API,因而得以被举例javadoc此类的工具文书档案化。Documented是三个标识评释,未有成员。

Annotation的不感到奇使用

Annotation被周围用于各样框架和库中,上面就罗列部分天下无敌的应用.

  Class:类定义
  Constructor:构造器定义
  Field:累的成员变量定义
  Method:类的方法定义
  Package:类的包定义

@Target

   @Target表明了Annotation所修饰的目的节制:Annotation可被用来
packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、布局方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的宣示中央银行使了target可进一层清楚其修饰的指标。

功能:用于描述注脚的采取范围(即:被描述的注释能够用在哪些地点)

 取值(ElementType)有:

    1.CONSTRUCTOEvoque:用于描述布局器
    2.FIELD:用于描述域
    3.LOCAL_VAENCOREIABLE:用于描述局部变量
    4.METHOD:用于描述方法
    5.PACKAGE:用于描述包
    6.PARAMETE翼虎:用于描述参数
    7.TYPE:用于描述类、接口(包含申明类型State of Qatar 或enum注脚

利用示例:

  1 /***
  2  *
  3  * 实体注解接口
  4  */
  5 @Target(value = {ElementType.TYPE})
  6 @Retention(value = RetentionPolicy.RUNTIME)
  7 public @interface Entity {
  8     /***
  9      * 实体默认firstLevelCache属性为false
 10      * @return boolean
 11      */
 12     boolean firstLevelCache() default false;
 13     /***
 14      * 实体默认secondLevelCache属性为false
 15      * @return boolean
 16      */
 17     boolean secondLevelCache() default true;
 18     /***
 19      * 表名默认为空
 20      * @return String
 21      */
 22     String tableName() default "";
 23     /***
 24      * 默认以""分割注解
 25      */
 26     String split() default "";
 27 }

自定义Annotation

JSE5.0事后我们得以自定义Annotation。上边正是三个简短的事例。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodAnnotation {

}

下边的Person对象使用了自定义的MethodAnnotation。

public class Person {

    public void eat() {
        System.out.println("eating");
    }

    @MethodAnnotation
    public void walk() {
        System.out.print("walking");
    }

}

我们得以经过反射获取Annotation的新闻。

 Class<Person> personClass = Person.class;
        Method[] methods = personClass.getMethods();
        for(Method method : methods){
            if (method.isAnnotationPresent(MethodAnnotation.class)){
                method.invoke(personClass.newInstance());
            }
        }

输出:

walking

大家也得以给自定义的Annotation加方法。

@Target(ElementType.TYPE)
public @interface personAnnotation {
    int id() default 1;
    String name() default "bowen";
}

上边是对personAnnotation的施用。

@personAnnotation(id = 8, name = "john")
public class Person {

    public void eat() {
        System.out.println("eating");
    }

    @MethodAnnotation
    public void walk() {
        System.out.print("walking");
    }

}

批注微电脑类库(java.lang.reflect.AnnotatedElementState of Qatar:

元注解

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

 

Hibernate

  • @Entity 修饰entity bean
  • @Table 将entity类与数据库中的table映射起来
  • @Column 映射列
  • @Id 映射id
  • @GeneratedValue 该字段是自增加的
  • @Version 版本调节或并发性调节
  • @OrderBy 排序准则
  • @Lob 大对象注脚

Hibernate还大概有大批量的关于联合的annotation和三回九转的annotation,这里就不意义列举了。

地点已经介绍完,修饰声明的主要字了,上边终于能够初叶介绍自定义注脚了。

功能:表示供给在怎么着等级保存该注释音讯,用于描述注脚的生命周期(即:被描述的笺注在什么样范围内有效)
取值(RetentionPoicy)有:

四.@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类型被开采,也许达到类世襲布局的顶层。
实例代码:

Retention
meta-annotation类型有独一的value作为成员,它的取值来自java.lang.annotation.RetentionPolicy的枚举类型值。具体实举例下:

方法1:<T extends Annotation> T getAnnotation(Class<T>
annotationClass卡塔尔国:
重临改程序成分上存在的、钦点项指标解说,假如该类型评释空中楼阁,则赶回null。
方法2:Annotation[]
getAnnotations(State of Qatar:重临该程序成分上存在的全数声明。
方法3:boolean isAnnotationPresent(Class<?extends Annotation>
annotationClass卡塔尔国:判断该程序成分上是还是不是带有钦定项目标注释,存在则赶回true,不然重返false。
方法4:Annotation[]
getDeclaredAnnotations(卡塔尔国:再次来到直接存在于此成分上的具有注释。与此接口中的其余艺术差别,该办法将忽略世袭的解说。(如果未有注释直接存在于此成分上,则赶回长度为零的七个数组。)该情势的调用者能够轻松改革再次来到的数组;那不会对另向外调拨运输用者重返的数组产生其余影响。

二.@Retention:
@Retention定义了该Annotation被保存的小时长度:有些Annotation仅出以后源代码中,而被编译器放弃;而另一些却被编写翻译在class文件中;编写翻译在class文件中的Annotation或者会被设想机忽视,而另一对在class棉被服装载时将被读取(请稳重并不影响class的实践,因为Annotation与class在运用上是被分别的)。使用那些meta-Annotation能够对
Annotation的“生命周期”约束。

三.@Documented:
@Documented用于描述其余品类的annotation应该被看作被申明的顺序成员的公共API,由此能够被比方javadoc此类的工具文书档案化。Documented是三个标记注脚,未有成员。

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

Java使用Annotation接口来代表前后相继成分前边的解说,该接口是具有Annotation类型的父接口。除此而外,Java在java.lang.reflect
包下新扩张了AnnotatedElement接口,该接口代表前后相继中能够采用注明的程序成分,该接口主要犹如下多少个实现类:

要选拔评释,先要领悟注明,先要精通下Java中二种评释
1.元注解:
元申明的功能就是承担(注解或描述其余评释State of Qatar。Java5.0定义了4个正经的meta-annotation类型,它们被用来提供对其余annotation类型作表明。
Java5.0概念的元证明:
1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited
那几个项目和它们所支撑的类在java.lang.annotation包中得以找到。下边大家看一下各类元声明的机能和相应分参数的采用验证。

  1.SOURCE:在源文件中有效(即源文件保留)
  2.CLASS:在class文件中有效(即class保留)
  3.RUNTIME:在运行时有效(即运行时保留)
@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 注解名 {定义体}
批注参数的可支撑数据类型:

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

举个例子来讲如下:

Annotation类型里面包车型地铁参数该怎么设定:
率先,只好用public或私下认可(default卡塔尔(قطر‎这三个访谈权修饰.举例,String
value(卡塔尔国;这里把措施设为defaul暗中认可类型;   
其次,参数成员只可以用基本类型byte,short,char,int,long,float,double,boolean多种基本数据类型和
String,Enum,Class,annotations等数据类型,甚至这一部分类型的数组.比如,String
value(State of Qatar;这里的参数成员就为String;  
其三,假设独有一个参数成员,最佳把参数名称设为”value”,后加小括号.例:下边包车型大巴例证FruitName注明就独有多个参数成员。
简单易行的自定义评释和选用注明实例:

@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;
}
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;
/**
 * 水果名字注解
 */
@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;
/**
 * 水果颜色注解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
    /**
     * 颜色枚举
     */
    public enum Color{ BULE,RED,GREEN};

    /**
     * 颜色属性
     */
    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("水果的名字是:苹果");
    }
}

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;

/**
 * 水果供应者注解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
    /**
     * 供应商编号
     * @return
     */
    public int id() default -1;

    /**
     * 供应商名称
     * @return
     */
    public String name() default "";

    /**
     * 供应商地址
     * @return
     */
    public String address() default "";
}
You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图