1.Annotation(注解)介绍
Annotation(注解)是JDK5.0及以后版本引入的,是那些插入到源代码中用于某种工具处理的标签,这些标签可以在源码层次上进行操作,或者处理编译器将他们纳入到注解类文件中。
注解不会改变对编写的程序的编译方式。java编译器对于包含注解和不包含注解的代码会生成相同的虚拟机指令。
在java中,注解是当做一个修饰符(就是诸如public,static之类的关键词)的,它被置于被注解项之前,中间没有分号。
注解本身并不会做任何事情,它需要工具支持才会有用。比如JUnit4的@Test注解自身不会做任何事情,JUnit会识别并调用所有标识为@Test的方法,这种识别处理
一般是采用代理模式,通过反射来调用,后面会说明。
它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以'@注解名'在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解、单值注解、完整注解三类。它们都不会直接影响到程序的语义,只是作为注解(标识)存 在,我们可以通过反射机制编程实现对这些元数据(用来描述数据的数据)的访问。另外,你可以在编译时选择代码里的注解是否只存在于源代码级,或者它也能在class文件中出现。
在javaEE经典的SSH框架中(Strtus,Spring,hibernate),都可以用过使用注解来减少配置,提高系统的灵活性,所以,学习注解,是很有必要的一件事。
根据annotation的使用方法和用途主要分为以下几类:
1)内建Annotation——Java5.0版在java语法中经常用到的内建Annotation:@Override, @SuppressWarnings等。
2)使用第三方开发的Annotation类型
3)开发者自定义Annotation:由开发者自定义Annotation类型。
前两种是我们经常使用的,第三种经常出现在框架开发中。
2.内建Annotation
也就是
jdk提供的注解,最常被使用,下面举例:
1)@Override注释能实现编译时检查,你可以为你的方法添加该注释,以声明该方法是用于覆盖父类中的方法。如果该方法不是覆盖父类的方法,将会在编译时报错。例如我们为某类重写toString()方法却写成了tostring(),并且我们为该方法添加了@Override注释;
Jdk中可以看到源码:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override
{
}
其中@Target,@Retention啥意思呢?这些就是后面要介绍的元注解,专门用来注解其他注解的注解。这里先大概知道是什么就可以了。
2)@Deprecated的作用是对不应该在使用的方法添加注释,当编程人员使用这些方法时,将会在编译时显示提示信息,它与javadoc里的@deprecated标记有相同的功能,准确的说,它还不如javadoc @deprecated,因为它不支持参数,
注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。
3)@SuppressWarnings与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下:
deprecation: 使用了过时的类或方法时的警告
unchecked: 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型.
fallthrough: 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告
path: 在类路径、源文件路径等中有不存在的路径时的警告
serial: 当在可序列化的类上缺少 serialVersionUID 定义时的警告
finally: 任何 finally 子句不能正常完成时的警告
all: 关于以上所有情况的警告.
如:
@SuppressWarnings({"deprecation","unchecked"})
void callDeprecatedMethod(List horseGroup)
{
}
3.第三方提供的注解
这部分也是平时使用比较多的,比如spring的注解,jpa的注解等,用来完成一些配置文件的功能。关于以上两部分我们知道怎么使用就可以了,如果要想知道这些注解是怎么起作用的,那就要理解自定义注解的创建和使用了。
4.开发者自定义Annotation:由开发者自定义Annotation类型。
要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法。
4.1 元注解
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited
这些类型和它们所支持的类在java.lang.annotation包中可以找到。下面我们看一下每个元注解的作用和相应分参数的使用说明。
@Target:
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
取值(ElementType)有:
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
使用实例:
@Target(ElementType.TYPE)
public @interface Table {
/**
* 数据表名称注解,默认值为类名称
* @return
*/
public String tableName() default "className";
}
@Target(ElementType.FIELD)
public @interface NoDBColumn
{
}
@Retention:
@Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class 被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对Annotation的“生命周期”限制。
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
取值(RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
Retention meta-annotation类型有唯一的value作为成员,它的取值来自java.lang.annotation.RetentionPolicy的枚举类型值。具体实例如下:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
public String name() default "fieldName";
public String setFuncName() default "setField";
public String getFuncName() default "getField";
public boolean defaultDBValue() default false;
}
Column注解的的RetentionPolicy的属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理。
@Documented:
@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
public String name() default "fieldName";
public String setFuncName() default "setField";
public String getFuncName() default "getField";
public boolean defaultDBValue() default false;
}
@Inherited:
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继 承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现, 或者到达类继承结构的顶层。
实例代码
@Inherited
public @interface Greeting {
public enum FontColor{ BULE,RED,GREEN};
String name();
FontColor fontColor() default FontColor.GREEN;
}
实例请参考:
http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html
4.2 自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就 是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认 值。
定义注解格式:
public @interface 注解名 {定义体}
注解参数的可支持数据类型:
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",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。
简单的自定义注解和使用注解实例:
/**
* 水果名称注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
String value() default "";
}
4.3 自定义注解的使用及注解处理器
注解处理器通常是采用反射和代理模式来实现对自定义注解的解析。
实例请参考:
http://www.infoq.com/cn/articles/cf-java-annotation
http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html
分享到:
相关推荐
自定义注解结合Hutool对SpringBoot接口返回数据进行脱敏 自定义注解结合Hutool对SpringBoot接口返回数据进行脱敏 自定义注解结合Hutool对SpringBoot接口返回数据进行脱敏 自定义注解结合Hutool对SpringBoot接口返回...
3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...
这个一个自定义注解实现给注解传递伪动态参数的小案例,可以在此自定义注解的基础上来记录接口的调用记录。
java 自定义注解验证 可自己添加所需要的注解,本案例中只写了三个自定义注解类 本案例只花了半天时间,如有不好之处请多提提意见。谢谢!
自定义注解实现拦截sql,并在sql中增加相应的条件 。 对应博客: https://blog.csdn.net/qq_37716298/article/details/120659139
自定义注解得使用,模拟spring通过注解方式创建bean实例!
SpringBoot AOP各种注解、自定义注解、鉴权使用案例SpringBoot AOP各种注解、自定义注解、鉴权使用案例SpringBoot AOP各种注解、自定义注解、鉴权使用案例
excel导入动态校验,自定义注解动态校验
包括Java自定义注解以及包括自定义注解的应用实例。以及注解相关知识的注解
看到别的博主写的几篇接绍注解相关的东西,觉得挺好的,mark一下 ... 自定义注解:...主要就是自定义了注解,使用了自定义注解,然后利用java的反射机制根据注解生成不同的sql语句
springboot 脱敏自定义注解 SpringAOP
通过一个超市的自动售卖机的例子,详细说明了java的自定义注解的使用。
自定义java注解开发,javabean中某方法添加该自定义注解,配置该方法相关信息指标,通过全局扫描该注解获取全部方法及相关指标,自动执行方法(本demo用于系统监控开发)
springboot自定义注解的demo;通过本案例实现了通过自定义注解的拦截的方法可以设置访问权限;通过拦截器获取指定方法上的自定义的注解,然后判断当前的接口需不要权限校验;然后通过对应的访问去处理;demo里面的代码...
java自定义注解实践,介绍详细!值得参考
自定义注解bindview 省去findviewbyid,直接在变量前边添加@BindView即可绑定控件
自定义注解实现由类自定生成数据库中的表,适合各种类型的数据库,本案例主要实现的时sql server和oracle
spring中自定义注解(annotation)与AOP中获取注解.通过实例演示自定义注解。
SpringBoot 、Shiro、 自定义注解权限控制
网上很多人想使用注解拦截spring mvc action中的一个方法,实现方法很多,一般是通过在拦截器中分析url路径来实现, 使用自定义注解的方式来标注要拦截的 action 中的某个方法, 没有很好的解决方法, 如果通过借助spring...