网站首页 > java教程 正文
摘要:
本篇主要内容有:Java注解的介绍、基本语法、反射方式实现注解处理器。
前言
? 正所谓只要功夫深,铁杵磨成针,坚持不懈,水滴石穿。学习也要坚持不懈,慢慢积累,才能达到以量变促成质变。在前进的过程中也要保持好良好的心态,不急不燥,脚踏实地,一步一个脚印。
注解的介绍
? 注解也被称为元数据,是Java SE5引入的重要的语言变化一,注解的出现为我们在代码中添加信息提供来了一种形式化的方法,使我们可以在稍后的某个时刻方便的使用这些数据。
注解的作用
- 生成描述符文件。
- 新的类定义。
- 减轻编写“样板”代码的负担。
- 使代码干净易读。
- 可以在编译期进行类型检查。
标准注解
? Java为我们提供了三种标准化的注解,见以下表格:
注解标识作用@Override表示当前的方法定义覆盖超类中的方法,如果一不小心拼写错误,或者签名方法对不上被覆盖的方法,编译器就会发生错误。@Deprecated如果使用了注解为它的元素,编译器会发出警告信息@SuppressWarnings关闭不当的编译器警告信息
注解的基本语法
定义一个Test注解:
package iuni.life;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by iuni.life on 16/8/29.
* yangfei's computer
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
? 可以看到注解的定义和接口的定义非常相似,事实上,与其他任何Java接口一样,注解也会编译成class文件。注解和接口最明显的区别是在@符号上,即注解定义时为@interface,接口为interface。
? 除了@符号外,定义的Test注解更像是一个空的接口。当我们定义一个注解的时候会需要一些元注解,如@Target和@Retention。其实在Java目前内置了三种标准注解(详见前面表格)和四种元注解。元注解专职负责注解其他的注解,以下是四种元注解的介绍:
? 在注解中一般都会包含一些元素以表示某些值,当分析处理注解时,程序或者工具可以利用这些值。注解的元素看起来就像接口的方法,唯一的区别就是你可以为其指定默认值。
? 没有元素的注解称为标记注解 ,上例定义的Test注解就是标记注解。
? 在Java中实现注解一般是按照以下步骤:定义注解—>实现注解处理器—>使用注解。注解处理器的实现方式分为两种,一种是用反射的方式实现,另一种则是使用apt工具实现,下面我们通过例子来学习这两种实现方式。
编写注解处理器
准备工作
? 在编写注解处理器之前我们需要知道注解的一些规则;
- 注解可以使用的元素所有基本类型(int、float、boolean等)。StringClassenumAnnotation以上类型的数组
- 默认值限制编译器对元素的默认值有些过分挑剔,首先元素不能有不确定的值,即元素必须要么有默认值,要么在使用注解的时候提供元素的值。其次,对于非基本类型的元素,无论是在源码声明时,或者是在注解接口中定义默认值时,都不能用null作为其值。这个约束使得处理器很难表现一个元素的存在或者缺失的状态,因为在每个注解的声明中,所有的元素都存在并且具有相应的值,那么我们怎么样表现元素的存在或缺失状态呢?我们可以定义一些特殊值,例如空字符串或者负数,用以表示某个元素不存在。
- 注解不支持继承不能使用关键字extends来继承某个@interface。
- 注解的方法不能有参数
使用反射方式实现
- 定义一个ReflectAnnotation注解:package iuni.life; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by iuni.life on 16/8/29. * yangfei's computer */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ReflectAnnotation { String author() default "iuni.life"; String date(); int version() default 1; }
- 使用反射的方式实现注解处理器: package iuni.life; import java.lang.reflect.Method; /** * Created by iuni.life on 16/8/29. * yangfei's computer */ public class ReflecAnnotationTracker { public static void trackerReflectAnnotation(Class cl) { //getDeclaredMethods 反射方法,获取cl类中所有的方法 for (Method method : cl.getDeclaredMethods()) { //getAnnotation()方法返回指定的类型的注解对象,这里就是ReflectAnnotation.class,如果没有该类型的注解则返回null ReflectAnnotation reflectAnnotation = method.getAnnotation(ReflectAnnotation.class); if (reflectAnnotation != null) { sys("ReflectAnnotation:--->author:" + reflectAnnotation.author() + ",date:" + reflectAnnotation.date() + ",version:" + reflectAnnotation.version()); } } } public static void sys(String detail) { System.out.println(detail); } }?
- 测试类: package iuni.life; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by iuni.life on 16/8/29. * yangfei's computer */ public class Client { public static void main(String[] args) { ReflecAnnotationTracker.trackerReflectAnnotation(Client.class); } @ReflectAnnotation(author = "www.iuni.life", date = "2016-08-27", version = 1) public void allTest() { } //因为author提供了默认值所以这里可以不使用 @ReflectAnnotation(date = "2016-08-28", version = 2) protected void test1() { } //因为author、version提供了默认值所以这里可以不使用 因为Date没有提供默认值,所以必须对date进行赋值 @ReflectAnnotation(date = "2016-08-28") private void test2() { } }
- 运行Client类的结果:
说明:
? 使用反射方式实现注解处理器最好还是了解一下Java反射方面的知识,这里列举的例子只是最简单的形式,只是起到了我们怎么使用反射的方式实现Java注解处理器的作用。
因篇幅原因,apt实现注解处理器详见 Java注解二。
后记
文章有不足之后,请大家多多指教,共同学习,共同进步。
猜你喜欢
- 2024-09-21 Java基础:注解,改变了编程的体验
- 2024-09-21 人手必备!Java8中的注解,你必须知道的几点
- 2024-09-21 java注解的使用(java注解的实现原理)
- 2024-09-21 不吹牛,撸个注解有什么难的(不吹牛的道理)
- 2024-09-21 终于弄懂了Spring@Component @Repository@Service的区别
- 2024-09-21 2020年最新Java全套教程注解(2020年最新兵役法)
- 2024-09-21 你知道Spring是如何处理注解的吗?
- 2024-09-21 注解梳理:深入理解Java注解类型(@Annotation)
- 2024-09-21 Java中的注解到底是如何工作的?(注解 java)
- 2024-09-21 JAVA 注解的几大作用及使用方法详解
你 发表评论:
欢迎- 最近发表
-
- class版本不兼容错误原因分析(class更新)
- 甲骨文Oracle公司为Java的最新LTS版本做出改进
- 「版本发布」Minecraft Java开发版 1.19.4-pre1 发布
- java svn版本管理工具(svn软件版本管理)
- 我的世界1.8.10钻石在第几层(我的世界1.7.2钻石在哪层)
- Java开发高手必备:在电脑上轻松切换多个JDK版本
- 2022 年 Java 开发报告:Java 8 八年不到,开发者都在用什么?
- 开发java项目,选择哪个版本的JDK比较合适?
- Java版本选型终极指南:8 vs 17 vs 21特性对决!大龄程序员踩坑总结
- POI Excel导入(poi excel导入附件)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)