关于注解你需要知道的
来源:互联网 发布:360免费wifi软件 编辑:程序博客网 时间:2024/06/08 07:40
转载请标明出处:
http://blog.csdn.net/guangzq/article/details/74644624
本文出自祝起光的博客
什么是注解
注解是 Java 5 的一个新特性。注解是插入你代码中的一种注释或者说是一种元数据(meta data)。这些注解信息可以在编译期使用预编译工具进行处理(pre-compiler tools),也可以在运行期使用 Java 反射机制进行处理。这里存在着一个基本的规则:Annotation不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的执行。注解的行为就像
系统内置标准注解:
注解的语法比较简单,除了@符号的使用外,他基本与Java固有的语法一致,JavaSE中内置三个标准注解,定义在java.lang中:
- @Override:用于修饰此方法覆盖了父类的方法;
- @Deprecated:用于修饰已经过时的方法;
- @SuppressWarnnings:用于通知java编译器禁止特定的编译警告。
元注解
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
- @Target,
- @Retention,
- @Documented,
- @Inherited
下面一一说一下每个元注解的参数使用和作用
@Target
@Target注解的作用目标。说明了注解所修饰的对象范围,可以更加清晰注解所修饰的目标。
作用:描述注解的使用范围,即注解用在什么地方
举例:
@Target(ElementType.METHOD)public @interface MethodAnnotation { String value() default "";}@Target(ElementType.FIELD)public @interface FieldAnnotation { String value() default "";}
注解MethodAnnotation可以用来描述方法,FieldAnnotation可以用来描述字段、枚举的常量。
@Retention
@Retention定义了该注解的时间长短,即注解的生命周期。
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Person { public String name() default "fieldName"; public String sex() default "fieldSex";}
Person注解的的RetentionPolicy的属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理
@Documented
@Documented将此注解包含在Javadoc中。用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如Javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Person { public String name() default "fieldName"; public String sex() default "fieldSex";}
@Inherited
允许子类继承父类中的注解。使用很少。
自定义注解
@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
定义注解格式:
public @interface 注解名 {定义体}
举例:
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface RapperName { String value() default "";}
注解参数的可支持数据类型:
- 1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
- 2.String类型
- 3.Class类型
- 4.enum类型
- 5.Annotation类型
- 6.以上所有类型的数组
Annotation类型里面的参数该怎么设定:
- 第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;
- 第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;
- 第三,如果只有一个参数成员,最好把参数名称设为”value”,后加小括号.
下面用一个自定义注解的例子来说明一下使用:
最近《中国有嘻哈》挺火,那我们就让rapper吴亦凡来dis一句 “你有freestyle吗?”
/** * Created by zhuqiguang on 17/7/6. * rapper名字 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface RapperName { String value() default "";}
是哪里的rapper呢?
/** * Created by zhuqiguang on 17/7/6. */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface RapperAdress { //住址枚举 enum Adress{SICHUAN, BEIJING, SHANDONG} //住址属性 Adress rapperAdress() default Adress.BEIJING;}
rapper需要嘻哈装备
/** * Created by zhuqiguang on 17/7/6. */public @interface RapperEquipment { //语言选项 enum Language{CHINESE, ENGLISH} //语言属性 Language rapperLanguage() default Language.CHINESE; //说唱歌词 String rapperLyrics() default ""; //穿戴选项 enum Clothing{GLASSES, RING} Clothing rapperClothing() default Clothing.GLASSES;}
组合成一个rapper
/** * Created by zhuqiguang on 17/7/6. */public class Rapper { @RapperName("吴亦凡") private String rapperName; @RapperAdress(rapperAdress = RapperAdress.Adress.BEIJING) private String rapperAdress; @RapperEquipment(rapperLanguage = RapperEquipment.Language.CHINESE, rapperLyrics = "你有free style吗?", rapperClothing = RapperEquipment.Clothing.GLASSES) private String rapperEquipment; public String getRapperName() { return rapperName; } public void setRapperName(String rapperName) { this.rapperName = rapperName; } public String getRapperAdress() { return rapperAdress; } public void setRapperAdress(String rapperAdress) { this.rapperAdress = rapperAdress; } public String getRapperEquipment() { return rapperEquipment; } public void setRapperEquipment(String rapperEquipment) { this.rapperEquipment = rapperEquipment; }}
利用反射来获取rapper字段
/** * Created by zhuqiguang on 17/7/6. */public class RapperUtils { private static String Tag = "RapperUtils"; public static void getRapperInfo (Class<?> clazz){ String rapperName = "rapper名字: "; String rapperAdress = "rapper住址: "; String rapperEquipment = "rapper装备: "; Field[] declaredFields = clazz.getDeclaredFields(); for(Field field: declaredFields) { if (field.isAnnotationPresent(RapperName.class)) { RapperName name = field.getAnnotation(RapperName.class); Log.d(Tag, rapperName + name.value()); }else if (field.isAnnotationPresent(RapperAdress.class)) { RapperAdress adress = field.getAnnotation(RapperAdress.class); Log.d(Tag, rapperAdress + adress.rapperAdress().toString()); }else if (field.isAnnotationPresent(RapperEquipment.class)) { RapperEquipment equipment = field.getAnnotation(RapperEquipment.class); String equ = "语言: " + equipment.rapperLanguage().toString() + " ,歌词: " + equipment.rapperLyrics() + " ,穿戴: " + equipment.rapperClothing().toString(); Log.d(Tag, rapperEquipment + equ); } } }}
main函数中调用
RapperUtils.getRapperInfo(Rapper.class);
输出结果:
rapper住址: BEIJING rapper装备: 语言: CHINESE ,歌词: 你有free style吗? ,穿戴: GLASSES rapper名字: 吴亦凡
总结
注解在对于框架的构建以及简约代码有很大的作用,像Android中的通讯组件Router就是利用注解来设置通讯的路径,还有著名的Butternife,其原理是ButterKnifeProcessor在编译时会扫描你的Java代码中所有使用@BindView,@OnClick等注解,如果发现存在注解,那么通过一系列的解析工作,生成一个类似AnnotationActivity## ViewBinder(className##ViewBinder)的Java类,这个类实现了ViewBinder接口。这个生成类中实现了各注解对应的代码像@BindView最终会执行findViewById(),@OnClick最终会执行setOnClickListener()
本文demo中的源码地址:
- https://github.com/guangzq/AnnotationDemo.git
参考
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
- 关于注解你需要知道的
- 关于java编译时注解你需要知道的二三事。解除你的顾虑!
- 关于MongoDB你需要知道的几件事
- 关于MongoDB你需要知道的几件事
- 关于MongoDB你需要知道的几件事
- 关于MongoDB你需要知道的几件事
- 关于MongoDB你需要知道的几件事
- 关于 MongoDB 你需要知道的几件事
- 关于MongoDB你需要知道的几件事
- 你需要知道的关于VPN技术
- 关于MongoDB你需要知道的几件事
- 关于MongoDB你需要知道的几件事
- 关于git你需要知道的
- 关于MongoDB你需要知道的几件事
- 关于MongoDB你需要知道的几件事
- 关于Weex你需要知道的一切
- 关于AnsycTask你需要知道的几个问题
- 关于 service 你需要知道的
- Java并发之UncaughtExceptionHandler
- Android NDK: From Elementary To Expert Episode 14
- 夯实JAVA之泛型详解一代龙套篇
- apache2跨域js请求解决方案
- AeroSpike安装及启动
- 关于注解你需要知道的
- 抽象类的理解
- javascript时间戳和日期字符串相互转换
- Kmeans算法的Python实现
- VS2015 无法解析的外部符号 __vsnwprintf_s
- Andorid手机从Type-C接口读取U盘数据
- anjular 一些常用的方法
- 7-7
- Mybatis一对一、一对多关联查询