java注解(1)

来源:互联网 发布:在线ktv软件 编辑:程序博客网 时间:2024/06/06 23:15



(1)注解是什么?

记得刚开始在学习java时,使用eclipse编写代码时,在写代码时,在某些方法上或者属性上总会出现一些以@开始的修饰,就像下面代码:

package annotation;import java.util.ArrayList;import java.util.Date;import java.util.List;public class HelloAnnotation {//用来标注忽略警告信息@SuppressWarnings("rawtypes")public List hobbies = new ArrayList<>();public String name;//用来标注这个方法是被重写的@Overridepublic String toString() {// TODO Auto-generated method stubreturn super.toString();}public static void main(String[] args) {Date date = new Date();//用来标注忽略警告信息@SuppressWarnings("deprecation")int year = date.getYear();}//用来标注这个方法已经过期@Deprecatedpublic void sayHello(){System.out.println("hello " + this.name);}}
一开始到没在乎,后来再学习java的一些ADF(应用程序框架)时,才了解到这写都是注解。今天在看SpringBoot时又使用到了这些东西,所以就打算好好的整理一下。

好的,废话不多说了,直接说干货吧。


java的Annotation的注解说白了就是对java类中各个部分的额外描述,说的上档次一点就是代码级别的描述,也就是我们经常说的元数据。对于java中的反射,我想大家肯定不陌生,反射说白了就是对java各个部分的结构记录和描述,而注解呢,只是又多了层。。。

在这里,小编特别要强调的一点就是,Annotation仅仅是元数据的描述,就像之前大家熟悉的XML一样,它和业务逻辑没有关系。它只是提供它定义属性的信息,而我们可以使用这些属性信息进行业务逻辑的编写。这也是常见的一些框架的注解实现,典型的有spring,如@Resouce,在spring容器启动时,会加载beans.xml文件,并开始实例一些bean,在实例这些bean的过程中,它就会读取这些元数据,并实现相应的业务逻辑,Hibernate也是如此的。。。说到这,我怎么感觉有点深了,我们还是先自己定义一个注解玩玩之后,再聊聊这些上档次的话题吧。。。


(2)怎么写注解

1.我们先自定义一个注解,如下代码:

package annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface MyAnnotation {//定义参数String id();//如果只使用value这个属性,可以不用声明name//可以声明一个default值String value() default "default_value";}

2.接下来,我们就解读一些上述代码:

a) @interface 这个关键字就是用来声明注解的,java的Annotation说到底还是一个java类,只是声明的关键字由class变成了@interface

b)@Target  ,这个关键字是说明该注解用于什么地方,类?属性?方法?。。。ElementType的参数如下;

ElementType.CONSTRUCTOR:  构造器声明

ElementType.FIELD: 成员变量、属性、对象(包括enum实例)

ElementType.LOCAL_VARIABLE: 局部变量声明

ElementType.METHOD: 方法声明

ElementType.PACKAGE:包声明

ElementType.TYPE:类、接口(包括注解类型)或enum声明

c)@Retention  这个关键字说明保存该注解的级别,可选的RetetionPolicy参数包括:

RetentionPolicy.SOURCE:注解将被编译器丢弃

RetentionPolicy.CALSS:注解在class文件中可用,但会被JVM丢弃

RetentionPolicy.RUNTIME JVM将在运行期也保留该注解信息,因此可以通过反射机制读取注解的信息,这也是我们经常用到的。

d)Document  说明该注解在javadoc中

e)Inherited 说明子类继承父类中的注解

f )使用@interface自定义一个注解时,自动继承了java.lang.annotation.Annotation接口,并且不能继承其他的注解或者接口。

注解参数支持的类型有:

* 所有基本类型

* Stirng类型

* Class类型

* Enum类型

* Annotation类型

* 以上所有类型的数组

由上述描述,我们知道,上述代码,定义了一个自定义的注解-----》MyAnnotation,它可以使用在类(接口)上、属性、方法上,并且拥有两个参数,

id和value,value还有一个默认的值,“default_value”


(3) 怎么使用注解

上一节,我们自定义了一个注解,怎么使用呢? 如下代码:

package annotation;//在类上加注解@MyAnnotation(id="class-id",value="class-val")public class UserMyAnnotation {//在id属性上加上注解@MyAnnotation(id="field-id")public int id;@MyAnnotation(id="method-id")public void testAnnotation(){System.out.println("id="+this.id);}}


代码说明:

注解的使用就很简单了,直接在写在要说明位置的上方即可,参数蚕蛹key-value的格式,并用“,”隔开


(4)注解的解析

从刚开始我就一直在强调,注解只是元数据,单纯的看它没有实际意义,只是描述。而我们在开发中要真正用到自定义的注解,肯定不只是为了简简单单的说明,

如果是这样的话,我们还不如直接用注释,就不用这么大费周章的使用注解这个麻烦玩意了。

通过第2小节和第3小节,我们学会了怎么定义注解和使用注解,这只是准备工作,只是为了我们才开发中真正使用注解来实现相应的业务逻辑做准备。

不多说,下面的代码展现了我们如何接卸注解,解析注解需要用到java的反射,如果你还不了解的话,可以参阅小编之前写的反射这一章节。


package annotation;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ResolveAnnotation {public static void main(String[] args) throws Exception {//类上的注解readTypeAnnotation();//方法上的注解readMethodAnnotation();//属性上的注解readFieldAnnotation();}//解析类上的注解public  static void readTypeAnnotation() throws Exception{System.out.println("----------类上的注解---------------");//通过反射获得类名Class<?> c = Class.forName("annotation.UserMyAnnotation");//获取类自身的注解类MyAnnotation an = c.getDeclaredAnnotation(MyAnnotation.class);//获取 属性值System.out.println("value="+an.value());System.out.println("id="+an.id());}//解析方法上的注解public static void readMethodAnnotation() throws Exception{System.out.println("----------方法上的注解---------------");//通过反射获得类名Class<?> c = Class.forName("annotation.UserMyAnnotation");//获取类自己的方法Method method = c.getDeclaredMethod("testAnnotation");//获取自己方法上的注解类MyAnnotation an = method.getDeclaredAnnotation(MyAnnotation.class);//获取 属性值System.out.println("value="+an.value());System.out.println("id="+an.id());}//解析属性上的注解public static void readFieldAnnotation() throws Exception{System.out.println("----------属性上的注解---------------");//通过反射获得类名Class<?> c = Class.forName("annotation.UserMyAnnotation");//获取类自己的属性Field field = c.getDeclaredField("id");//获取自己属性上的注解类MyAnnotation an = field.getDeclaredAnnotation(MyAnnotation.class);//获取 属性值System.out.println("value="+an.value());System.out.println("id="+an.id());}}

上述代码只是抛砖引玉,只是特定的解析了某一个注解类,读者可自行查阅资料,解析多个注解类。



总结:

java的注解仅仅是元数据,和业务逻辑无关。

java的注解仅仅是元数据,和业务逻辑无关。

java的注解仅仅是元数据,和业务逻辑无关。

        重要的话要说三遍










0 0
原创粉丝点击