注解基础
来源:互联网 发布:华南理工大学网络 编辑:程序博客网 时间:2024/06/06 03:14
注解系列
注解基础
APT
JavaPoet
0x00 概述
本文主要是介绍注解的基础知识,为后面的APT和JavaPoet打下基础
0x01 什么是注解
注解(Annotation)是Java5的一个新特性,是插入在代码中的一种注释或者说是一种元数据(meta data),这些注释信息可以在编译期使用预编译工具进行获取处理,也可以在运行期使用Java反射机制来获取,这取决于你的注解类型。
0x02 注解的语法及其定义
在Android中注解经常存在我们代码中:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main4); getIntentData(); }
上面的@Override
就是系统的注解,表明这是个重写方法,点击源码可以看到长成下面的样子
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
实际中会带有一些参数
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface run_methodInfo { String name() default "long"; String data(); int id() default 365; }
@Retention @Target @Document @Inherited四种 是元注解即 “注解的注解”
@Target 表示该注解目标,可能的 ElemenetType 参数包括:
- ElemenetType.CONSTRUCTOR 构造器声明
- ElemenetType.FIELD 域声明(包括 enum 实例)
- ElemenetType.LOCAL_VARIABLE 局部变量声明
- ElemenetType.METHOD 方法声明
- ElemenetType.PACKAGE 包声明
- ElemenetType.PARAMETER 参数声明
- ElemenetType.TYPE 类,接口(包括注解类型)或enum声明
@Retention 表示该注解的生命周期,可选的 RetentionPolicy 参数包括
- RetentionPolicy.SOURCE 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃注解将被编译器丢弃
- RetentionPolicy.CLASS 注解被保留到class文件,但jvm加载class文件时候被遗弃
- RetentionPolicy.RUNTIME 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;,因此可以通过反射机制读取注解的信息
@Documented 指示将此注解包含在 javadoc 中
@Inherited 指示允许子类继承父类中的注解
使用注解需要遵守它的规则:
- Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口.
- 参数成员只能用public或默认(default)这两个访问权修饰
- 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
- 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法(分为编译期还是运行期)
0x03 使用
(这里仅介绍最常见的运行期的注解,编译期注解涉及到apt、javapoet会单独再开一篇介绍)
Step One 定义注解
先看三个Runtime注解,包括类、方法、字段,
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface run_classInfo { String value();}@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface run_methodInfo { String name() default "long"; String data(); int id() default 365;}@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface run_fieldInfo { int[] value();}
Step two 使用这些注解,
@run_classInfo("类注解RunTime Class")public class RunTimeTest { @run_fieldInfo(value = {77, 88}) public String fieldInfo = "filedInfo"; @run_fieldInfo(value = {163}) public int id = 55; @run_methodInfo(name = "彩笔学长", data = "finance") public static String getMethod() { return RunTimeTest.class.getSimpleName(); }}
使用反射解析注解
/** * 解析运行时注解 */ private void showRunTimeInfo() { StringBuffer sb = new StringBuffer(); //获取Class 注解 Class<?> clazz = RunTimeTest.class; Constructor<?>[] constructors = clazz.getConstructors(); //获取包含的注解类信息 run_classInfo runClassInfo = clazz.getAnnotation(run_classInfo.class); if (runClassInfo != null) { //获取class注解 sb.append("Class注解: ").append("\n"); sb.append(Modifier.toString(clazz.getModifiers())).append(" ") .append(clazz.getSimpleName()).append("\n"); sb.append("注解值:").append("\n") .append(runClassInfo.value()).append("\n\n"); } //获取Field注解 sb.append("Field注解:").append("\n"); Field[] fields = clazz.getDeclaredFields(); //获取自身的不包括继承类 for (Field field : fields) { //获取field注解类信息 run_fieldInfo fieldInfo = field.getAnnotation(run_fieldInfo.class); if (fieldInfo != null) { sb.append(Modifier.toString(field.getModifiers())).append(" ") .append(field.getType().getSimpleName()).append(" ") .append(field.getName()).append("\n"); sb.append("注解值: ").append("\n") .append(Arrays.toString(fieldInfo.value())).append("\n\n"); } } //获取Method 注解 sb.append("Method注解: ").append("\n"); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { run_methodInfo methodInfo = method.getAnnotation(run_methodInfo.class); if (methodInfo != null) { sb.append(Modifier.toString(method.getModifiers())).append(" ") .append(method.getReturnType().getSimpleName()).append(" ") .append(method.getName()).append("\n"); sb.append("注解值:").append("\n"); sb.append("name: ").append(methodInfo.name()).append("\n"); sb.append("data: ").append(methodInfo.data()).append("\n"); sb.append("id: ").append(methodInfo.id()).append("\n"); } } tvDes.setText(sb.toString()); }
0x04 参考文献
- http://www.cnblogs.com/lbangel/p/3523741.html
- http://blog.csdn.net/github_35180164/article/details/52107204
0 0
- 注解基础
- 注解基础
- Java注解(1)-注解基础
- java基础-注解一-注解基础
- spring2.5注解基础
- (32)基础加强&注解
- 基础加强:注解
- 基础加强- 注解(Annotation)
- JAVA基础加强:注解
- java基础学习-注解
- java基础之注解
- Java基础:注解
- Java注解Annotation基础
- java注解基础
- Java基础 注解
- Java注解Annotation基础
- Spring MVC-----基础注解
- springMVC基础注解
- HTML中怎么设置超链接字体颜色和点击后的字体颜色
- MySQL Index详解
- 图论 无向图的双连通分量(模板) LA5135
- mysql复制工作方式
- 通过 lua 进行 nginx redis 访问控制
- 注解基础
- 如何学习安卓自定义View有这些足够了
- Yamicsoft.Windows.10.Manager.v2.0.4.Incl.Keygen.and.Patch-AMPED
- 17.玩转Spring Boot 集成Dubbo
- 第十九期 Android中修改GPS数据实验《手机就是开发板》
- 获取本机在Internet网络的广域网IP
- linux 下 apache启动、停止、重启命令
- 对于CDHtmlDialog和JavaScript、HTML配合使用的一些技术总结
- [AHK]在Excel中用热键创建超链接