一、语法

注解也属于一种类型

public @interface MyTestAnnotation {
}

用@interface描述

根据情况可以应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。

@MyTestAnnotation
public class MyTestClass {
}

二、元注解

用于修饰注解,就是注解的注解,元注解是一种基本注解。

目前元注解有@Retention、@Documented、@Target、@Inherited、@Repeatable五种。

1.@Retention 定义注解的生命周期

RetentionPolicy.SOURCE : 注解只在源码阶段保留,在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。例如:@Override, @SuppressWarnings这类注解。
     RetentionPolicy.CLASS : 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中,
在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
     RetentionPolicy.RUNTIME : 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取,始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。自定义的注解通常使用这种方式。

@Retention(RetentionPolicy.RUNTIME)
public @interface MyTestAnnotation { }

2.@Target 当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。表示该注解用于什么地方,比如类、接口、方法等。默认值为任何元素,表示该注解用于什么地方。

可用的ElementType参数包括:

ElementType.ANNOTATION_TYPE 可以给一个注解进行注解

ElementType.CONSTRUCTOR 构造方法进行注解
ElementType.FIELD 成员变量、对象、属性(包括enum实例)
ElementType.LOCAL_VARIABLE用于描述局部变量
ElementType.METHOD用于描述方法
ElementType.PACKAGE用于描述包
ElementType.PARAMETER用于描述参数
ElementType.TYPE用于描述类、接口(包括注解类型) 或enum声明

3.@Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。

4.@Inherited – 定义该注释和子类的关系

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

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyTestAnnotation {
}
@MyTestAnnotation
public class MyTestClass {
}
public class MySubTestClass extends MyTestClass {
}

MySubTestClass类继承其父类的注解

5.@Repeatable - 指定该注解可重复使用

使用@Repeatable修饰表示该注解可以为重复使用。@Repeatable是 Java 1.8 才加进来的。

@interface Persons {
    Person[]  value();
} @Repeatable(Persons.class)
@interface Person{
    String role default "";
} @Person(role="worker")
@Person(role="coder")
@Person(role="husband")
public class Tom{ }

三、注解的属性

注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Target(ElementType.TYPE)
public @interface MyTestAnnotation {
    public int id() default -1;
    public String name() default "hello world";
}

上述代码定义了id和name两个属性,并且定义了缺省值。

在使用的时候,我们应该给它们进行赋值。

赋值的方式是在注解的括号内以 value=”” 形式,多个属性之前用 ,隔开,如果不赋值,则私用缺省。

@MyTestAnnotation(id = 1000,name = "I love this game")
public class MyTest2Class {
}

需要注意的是,在注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组。

注解中属性可以有默认值,默认值需要用 default 关键值指定。

因为有默认值,所以无需要再在 @ MyTestAnnotation后面的括号里面进行赋值了,这一步可以省略。

@MyTestAnnotation
public class MyTestClass {
}

还有一种情况,

如果一个注解内仅仅只有一个名字为 value 的属性时(属性必须是value这个字),应用这个注解时可以直接接属性值填写到括号内。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CheckNum {
    String value();
}

@MyTestAnnotation
public class MyTestClass {
    @CheckNum("true")
    private int myflag;
}

最后,还需要注意的一种情况是一个注解没有任何属性。比如

@Retention(RetentionPolicy.RUNTIME)
public @interface CheckString {
}

那么在应用这个注解的时候,括号都可以省略。

@MyTestAnnotation
public class MyTestClass {
    @CheckNum("true")
    private int myflag;

@CheckString
    private String myStr;
}

四、获取注解

注解给类或者方法等打上标签,最终是程序在编译或运行时读取做出相应的动作。

获取注解本质上是采用反射。

1.定义注解

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Target(ElementType.TYPE)
public @interface MyTestAnnotation {
    public int id() default -1;
    public String name() default "hello world";
}
 

@Retention(RetentionPolicy.RUNTIME)
public @interface CheckNum {
    String value();
}

 

@Retention(RetentionPolicy.RUNTIME)
public @interface CheckString {
}

 

2.给类加注解

@MyTestAnnotation
public class MyTestClass {
    @CheckNum("true")
    private int myflag;

@CheckString
    @CheckNum("false")
    private String checkMyStr(String str)
    {
        return "";
    }

}

@MyTestAnnotation(id = 1000,name = "I love this game")
public class MyTest2Class {
}
public class MySubTestClass extends MyTestClass {
}

3.获取注解

private static void testAnnotation() throws Exception
{
    boolean isAnnotation = MyTestClass.class.isAnnotationPresent(MyTestAnnotation.class);
    if(isAnnotation) {
        MyTestAnnotation myTestAnnotation = MyTestClass.class.getAnnotation(MyTestAnnotation.class);
        System.out.println("id:" + myTestAnnotation.id());
        System.out.println("name:" + myTestAnnotation.name());
    }

isAnnotation = MyTest2Class.class.isAnnotationPresent(MyTestAnnotation.class);
    if(isAnnotation) {
        System.out.println("");
        MyTestAnnotation myTestAnnotation = MyTest2Class.class.getAnnotation(MyTestAnnotation.class);
        System.out.println("id:" + myTestAnnotation.id());
        System.out.println("name:" + myTestAnnotation.name());
    }

isAnnotation = MySubTestClass.class.isAnnotationPresent(MyTestAnnotation.class);
    if(isAnnotation) {
        System.out.println("");
        MyTestAnnotation myTestAnnotation = MySubTestClass.class.getAnnotation(MyTestAnnotation.class);
        System.out.println("id:" + myTestAnnotation.id());
        System.out.println("name:" + myTestAnnotation.name());
    }

System.out.println("获取类成员属性和方法的注解");
    //获取类成员属性和方法的注解
   
Field a = MyTestClass.class.getDeclaredField("myflag");
    a.setAccessible(true);
    //获取一个成员变量上的注解
   
CheckNum check = a.getAnnotation(CheckNum.class);

if ( check != null ) {
        System.out.println("check value:"+check.value());
    }

Method testMethod = MyTestClass.class.getDeclaredMethod("checkMyStr", String.class);

if ( testMethod != null ) {
        // 获取方法中的注解
       
Annotation[] ans =
testMethod.getAnnotations();
        for( int i = 0;i < ans.length;i++) {
            System.out.println("method 
annotation:"
+ans[i].annotationType().getSimpleName());
       
}
    }
}

输出结果:

id:-1

name:hello world

id:1000

name:I love this game

id:-1

name:hello world

获取类成员属性和方法的注解

check value:true

method 
annotation:CheckString

method 
annotation:CheckNum

符合输出预期。

												

java 注解使用笔记的更多相关文章

  1. Java注解学习笔记

    我们平常写Java代码,对其中的注解并不是很陌生,比如说写继承关系的时候经常用到@Override来修饰方法.但是@Override是用来做什么的,为什么写继承方法的时候要加上它,不加行不行.如果对J ...

  2. java注解学习笔记总结

    注解的理解 ① jdk 5.0 新增的功能 ② Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理.通过使用 Annotation,程序 ...

  3. Java注解和反射笔记

    Java注解和反射笔记 1 注解 1.1 定义 Annotation是从JDK1.5开始引入的技术 作用 不是程序本身,可以对程序作出解释 可以被其他程序(编译器等)读取 格式 @注释名,可以添加一些 ...

  4. Java注解--笔记

    @Override标签的作用@Override是伪代码,所以是可写可不写的.它表示方法重写,写上会给我们带来好处. 1.可以当注释用,方便阅读. 2.告诉阅读你代码的人,这是方法的复写. 3.编译器可 ...

  5. [原创]java WEB学习笔记96:Spring学习---Spring简介及HelloWord

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. 《Thinking In Java》阅读笔记

    <Thinking In Java>阅读笔记 前四章:对象导论. 一切都是对象. 操作符. 控制执行流程 public在一个文件中只能有一个,可以是一个类class或者一个接口interf ...

  7. 【iMooc】全面解析java注解

    在慕课上学习了一个关于java注解的课程,下面是笔记以及一些源码. Annotation——注解 1.JDK中的注解 JDK中包括下面三种注解: @Override:标记注解(marker annot ...

  8. 自定义Java注解(annotation)

    https://www.imooc.com/learn/456  笔记 Java从1.5开始引进注解. 首先解决一个问题,为什么要学习Java注解? 1.看懂别人写的代码,尤其是框架的代码 2.可以是 ...

  9. Java注解【一、概述】

    前面几篇Java学习笔记都是半夜写的,比较伤身体,今天开始想调整生物钟,早上起来学2小时,看看能坚持多久 本周目标: 1.JavaJDBC使用 2.JavaWeb编程 3.Java框架基础(反射+注解 ...

随机推荐

  1. apache和IIS共存,服务器对外统一使用80端口

    apache和IIS共用80端口为了PHP与ASP各自的执行效率,要在服务器上安装iis与Apache,但是无法同时使用80端口,否则其中必定有一个启动不了.让它们共存的并且访问网站不需要加端口号,解 ...

  2. Kubernetes 在网易云中的落地优化实践

    本文来自网易云社区 今天我跟大家讲的是 Kubernetes 在网易的一些实践,目的是抛砖引玉,看看大家在这个方向有没有更好的实践方法.简单介绍一下网易云.网易云是从最早 Kubernetes 1.0 ...

  3. Android 9 Pie震撼来袭 同步登陆WeTest

    WeTest 导读 2018年8月7日,Google对外发布最新 Android 9.0 正式版系统,并宣布系统版本Android P 被正式命名为代号“Pie”,最新系统已经正式推送包括谷歌Pixe ...

  4. hdu5305 Friends(dfs,多校题)

    Friends Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  5. hdu1848Fibonacci again and again(sg函数)

    Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  6. ReadyAPI 教程和示例(二)

    声明:如果你想转载,请标明本篇博客的链接,请多多尊重原创,谢谢! 本篇使用的 ReadyAPI版本是2.5.0 接上一篇: 4.修改SoapUI测试 本节将演示如何为测试用例添加测试步骤以及更改请求参 ...

  7. Matlab R2016a 破解教程

    郑重声明:图片来源于网络,在这里感谢图片提供者,我写这篇教程,是希望帮助后来者少走弯路,而且,这是一种比较简单有效的破解方法,针对网上那种修改本地文件的方法,在这里不做介绍,如果想体验,可自己百度或谷 ...

  8. 第五模块·WEB开发基础-第3章jQuery&Bootstrap

    01-jQuery介绍 02-如何使用jQuery 03-jQuery的入口函数 04-jQuery对象和JS对象的相互转换 05-jQuery如何操作DOM 06-底层选择器 07-基本过滤器 08 ...

  9. TW实习日记:第13天

    昨天困扰的问题终于解决了.因为是百度地图api提供的函数,所以这个解决办法并不适用于所有异步请求,仅仅针对百度地图api的调用接口函数和回调函数.有两种解决方法可以解决百度地图api中常出现的请求回调 ...

  10. 【Python 开发】第一篇:计算机基础

    一.计算机基础 首先Python是一门编程语言 语言: 那什么是语言? 语言就是一种事物与另一种事物沟通的介质.所以说编程语言是程序员跟计算机沟通的介质. 什么是编程: 准确来说就是程序员用计算机所能 ...