1.定义注解

使用@interface定义注解Annotation

  • 注解的参数类似无参数方法
  • 可以设定一个默认值(推荐)
  • 把最常用的参数命名为value(推荐)

2.元注解

2.1Target使用方式

使用@Target定义Annotation可以被应用于源码的那些位置

  • 类或接口:ElementType.TYPE
  • 字段:ElementType.FIELD
  • 方法:ElementType.METHOD
  • 构造方法:ElementType.CONSTRUCTOR
  • 方法参数:ElementType.PARAMETER
@Target({ElementType.METHOD,ElementType.FIELD})//可以传入1个或数组
public @interface Report{
int type() default 0;//设定默认值
String level() default "info";
String value() default "";//把最常用的参数命名为value
}

2.2Retention生命周期

使用@Retention定义Annotation的声明周期:

仅编译期:Retention.SOURCE,编译器在编译时直接丢弃,不会保存到class文件中

仅class文件: Retention.CLASS,该Annotation仅存储在class文件中,不会被读取

运行期:Retention.RUNTIME,在运行期可以读取该Annotation

如果@Retention不存在,则该Annotation默认为CLASS,通常自定义的Annotation都是RUNTIME。

    @Retention(RetentionPolicy.RUNTIME)
public @interface Report{
int type() default 0;//设定默认值
String level() default "info";
String value() default "";//把最常用的参数命名为value
}

2.3Repeatable可重复

使用@Repeatable定义Annotation是否可重复 JDK >= 1.8

Reports.java

package com.testAnno;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; //用于存储的容器注解
@Retention(RetentionPolicy.RUNTIME)
public @interface Reports {
Report[] value();
}

Report.java

package com.testAnno;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; //创建可重复注解
@Repeatable(Reports.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
// String value();
String info();
int type();
}

TestMyReport.java

package com.testAnno;

public class TestMyReport {
@Report(value="1")
public void repeatble1() {}
@Report("3")
@Report("2")
public void repeatable2() {} }

https://jingyan.baidu.com/article/a3761b2bf05f661576f9aaf3.html

2.4使用@Inherited定义子类是否可继承父类定义的Annotation

  • 仅针对@Target为TYPE类型的Annotation
  • 仅针对class的继承
  • 对interface的继承无效
package com.reflection;
import java.lang.annotation.*; @Inherited
@Target(ElementType.TYPE)
public @interface Report{
int type() default 0;
String level() default "info";
String value() default "";
}
@Report(type=1)
class Person1{ }
class Student1 extends Person1{}

3.定义Annotation

步骤:

  • 1.用@interface定义注解
  • 2.用元注解(meta annotation)配置注解

    * Target:必须设置

    * Retention:一般设置为RUNTIME

    * 通常不必写@Inherited,@Repeatable等等
  • 3.定义注解参数和默认值
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report{
int type() default 0;
String level() default "info";
String value() default "";
}

4.总结:

  • 使用@interface定义注解
  • 可定义多个参数和默认值,核心参数使用value名称
  • 必须设置@Target来指定Annotation可以应用的范围

廖雪峰Java4反射与泛型-2注解-2定义注解的更多相关文章

  1. 廖雪峰Java4反射与泛型-2注解-1使用注解

    1.Annotation定义 注解是放在Java源码的类.方法.字段.参数前的一种标签.如下 package com.reflection; import org.apache.logging.log ...

  2. 廖雪峰Java4反射与泛型-3范型-3编写泛型

    编写泛型类比普通的类要麻烦,而且很少编写泛型类. 1.编写一个泛型类: 按照某种类型(例如String)编写类 标记所有的特定类型例如String 把特定类型替换为T,并申明 Pair.java pa ...

  3. 廖雪峰Java4反射与泛型-2注解-3处理注解

    1.处理注解 注解本身对对代码逻辑没有任何影响 SOURCE类型的注解在编译期就被丢掉了 CLASS类型的注解仅保存在class文件中 RUNTIME类型的注解在运行期可以被读取 如何使用注解由工具决 ...

  4. 廖雪峰Java4反射与泛型-3泛型-7泛型和反射

    1.部分反射API是泛型 1.1获取反射API的泛型 部分反射API是泛型,如Class<T>是泛型 //如果使用Class,不带泛型,出现compile warning编译警告 Clas ...

  5. 廖雪峰Java4反射与泛型-3范型-4擦拭法

    1.擦拭法是Java泛型的实现方式. 编译器把类型视为Object. * 泛型代码编译的时候,编译器实际上把所有的泛型类型T统一视为Object类型.换句话说,虚拟机对泛型一无所知,所有的工作都是编译 ...

  6. 廖雪峰Java4反射与泛型-3范型-6super通配符

    1.super通配符 1.1super通配符第一种用法 泛型的继承关系 Pair<Integer>不是Pair<Number>的子类,如 static void set(Pai ...

  7. 廖雪峰Java4反射与泛型-3范型-5extends通配符

    1.泛型的继承关系: Pair<Integer>不是Pair<Number>的子类 add()不接受Pair<Integer> Pair.java package ...

  8. 廖雪峰Java4反射与泛型-1反射-2访问字段Field和3调用方法Method

    2.字段Field 2.1.通过Class实例获取字段field信息: getField(name): 获取某个public的field,包括父类 getDeclaredField(name): 获取 ...

  9. 廖雪峰Java4反射与泛型-1反射-1Class类

    1.Class类与反射定义 Class类本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建了唯一的Class实例. Class实例包 ...

随机推荐

  1. 2018.4.23 深入理解java虚拟机(转)

    深入理解java虚拟机 精华总结(面试) 一.运行时数据区域 Java虚拟机管理的内存包括几个运行时数据内存:方法区.虚拟机栈.本地方法栈.堆.程序计数器,其中方法区和堆是由线程共享的数据区,其他几个 ...

  2. 由testcase数据之分析

    一.获取data来源 1.利用openpyxl从excel表格获取数据,相较于xlrd,openpyxl可以将表格里的样式也传递过来的优势 xlrd  -----------------     ht ...

  3. 第一天 hello world

    二进制编译工具生成img软盘执行文件 二进制编译工具https://pan.baidu.com/s/1j3wAsFxTLWv17V55iNKJJw 利用Bz.exe工具写操作系统自启程序: 前0000 ...

  4. PHP黑魔法(该篇文章转自:http://www.91ri.org/12634.html 目的是作为自己的笔记方便查找)

    那些年我们学过的PHP黑魔法 作者:Matrix_ling 序 这里必须得说一下==和===这俩货的重要性.==是比较运算,它不会去检查条件式的表达式的类型===是恒等,它会检查查表达式的值与类型是否 ...

  5. hdu2732 Leapin' Lizards 最大流+拆点

    Your platoon of wandering lizards has entered a strange room in the labyrinth you are exploring. As ...

  6. Map 按Key排序 和 按Value排序

    https://www.cnblogs.com/binz/p/6671917.html 一.根据value排序 通用方法 public class MapUtil { public static &l ...

  7. Android 工具视频学习笔记_WDS

    1. 由于Android源码过于庞大,SourceInsight会经常卡死,不适合了.适合的是Android Studio, 非常好用.使用手册上有介绍如何安装. 编译安卓的过程说明手册中也有. 3. ...

  8. Scalable MySQL Cluster with Master-Slave Replication, ProxySQL Load Balancing and Orchestrator

    MySQL is one of the most popular open-source relational databases, used by lots of projects around t ...

  9. LoadRunner手写脚本、检查点、集合点、事务、思考时间

    手写脚本 什么时候要手写? 可以有条件手写脚本的场景有两类: 有接口说明文档 没有借口说明文档,要去录制,录制不了,抓包手写 所需函数 我们这里讲的例子是基于 http 协议的,也是常见的两种请求类型 ...

  10. python中in,not in,比较运算符,格式化输出,编码

    一,python中的in,和not in python中in的作用是检测或查找,例如: c = ‘你好大号胡覅但是啊飞碟说’ b = ‘你好’ print(b in c ) 结果: True c = ...