Java 注解学习笔记
注解说明
Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据。为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取注解内容。在编译器生成类文件时,注解可以被嵌入到字节码中。Java虚拟机可以保留注解内容,在运行时可以获取到注解内容。
内置注解
Java定义了一套注解,共有7个,3个在java.lang中,剩下4个在java.lang.annotation中。
1.作用在代码的注解是:
- @Override-检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
- @Deprecated-标记过时方法。如果使用该方法,会报编译警告。
- @SuppressWarnings-指示编译器去忽略注解中声明的警告。
2.作用在其他注解的注解(或者说元注解)是:
- @Retention-标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
- @Documented-标记这些注解是否包含在用户文档中。
- @Target-标记这个注解应该是哪种Java成员。
- @Inherited-标记这个注解是继承于哪个注解类(默认注解并没有继承于任何子类)
3.从Java7开始,额外添加了3个注解:
- @SafeVarargs-Java7开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
- @FunctionalInterface-Java8开始支持,标识一个匿名函数或函数式接口。
- @Repeatable-Java8开始支持,标识某注解可以在同一个声明上使用多次。
元注解
元注解就是上面说到的作用在其他注解上的注解。
1
生命周期类型 | 描述 | RetentionPolicy.SOURCE | 标记的注释仅保留在源级别中,并由编译器忽略。 | RetentionPolicy.CLASS | 标记的注释在编译时由编译器保留,但Java虚拟机(JVM)会忽略。 | RetentionPolicy.RUNTIME | 标记的注释由JVM保留,因此运行时环境可以使用它。 |
---|
2.@Documented:表明该注解标记的元素可以被Javadoc或类似的工具文档化
3.@Target:表明该注解可以应用的java元素类型
Target类型 | 描述 | ElementType.TYPE | 可以应用于类的任何元素。 | ElementType.FIELD | 可以应用于字段或属性。 | ElementType.METHOD | 可以应用于方法级注释。 | ElementType.PARAMETER | 可以应用于方法的参数。 | ElementType.CONSTRUCTOR | 可以应用于构造函数。 | ElementType.LOCAL_VARIABLE | 可以应用于局部变量。 | ElementType.ANNOTATION_TYPE | 可以应用于注释类型。 | ElementType.PACKAGE | 可以应用于包声明。 | ElementType.TYPE_PARAMETER | 1.8版本新增,应用于类型变量 | ElementType.TYPE_USE | 1.8版本新增,应用于任何使用类型的语句中(例如声明语句、泛型和强制转换语句中的类型) |
---|
4
5
自定义注解
其实说了这么多,都是一些总结性的知识点,我敢说到现在,大家还是对注解是云里雾里的。想要更好的认识注解,只有我们自己定义一个注解,来实现一个我们的注解,通过实现一个我们自己的注解来熟悉注解的工作流程。
Java中自定义注解和创建一个接口相似,声明一个注解要用到以下东西:
- 修饰符:访问修饰符必须为public,不写默认为pubic;
- 关键字:关键字为@interface;
- 注解名称:注解名称为自定义注解的名称,使用时还会用到;
- 注解类型元素:注解类型元素是注解中内容,可以理解成自定义接口的实现部分。
同时需要注意以下事项:
- 注解方法不能有参数;
- 注解方法的返回类型局限于原始类型,字符串,枚举,注解,或以上类型构成的数组;
- 注解方法可以包含默认值;
- 注解可以包含与其绑定的元注解,元注解为注解提供信息。
规则知道了,下面我来编码实现一个自定义的注解。比如我们在实现一个自定义的ORM框架的时候,都会通过注解来实现数据表名与JAVA类的映射,表字段与JAVA类字段的映射关系,下面就来简单实现这个功能。
定义Table注解:
packagecom.jellythink.annotation; importjava.lang.annotation.ElementType; importjava.lang.annotation.Retention; importjava.lang.annotation.RetentionPolicy; importjava.lang.annotation.Target; @Target(value={ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public@interfaceTable{ Stringvalue(); }
定义字段注解:
packagecom.jellythink.annotation; importjava.lang.annotation.ElementType; importjava.lang.annotation.Retention; importjava.lang.annotation.RetentionPolicy; importjava.lang.annotation.Target; @Target(value={ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public@interfaceFieldMapping{ Stringname(); Stringtype(); intlength(); }
应用注解:
packagecom.jellythink; importcom.jellythink.annotation.FieldMapping; importcom.jellythink.annotation.Table; @Table("tb_student") publicclassStudent{ @FieldMapping(name="id",type="int",length=10) privateintid; @FieldMapping(name="name",type="varchar",length=6) privateStringstuName; @FieldMapping(name="age",type="int",length=4) privateStringstuAge; //省略getterandsetter }
读取注解信息:
packagecom.jellythink; importcom.jellythink.annotation.Table; importcom.jellythink.annotation.FieldMapping; importjava.lang.reflect.Field; publicclassMain{ publicstaticvoidmain(String[]args){ try{ Classclazz=Class.forName("com.jellythink.Student"); //查询类上的注解 TabletbStudent=(Table)clazz.getAnnotation(Table.class); System.out.println(tbStudent.value()); //查询属性上的注解 FieldstuId=clazz.getDeclaredField("id"); FieldMappingfieldStuId=stuId.getAnnotation(FieldMapping.class); System.out.println(fieldStuId.name()+"--"+fieldStuId.type()+"--"+fieldStuId.length()); FieldstuName=clazz.getDeclaredField("stuName"); FieldMappingfieldStuName= stuName.getAnnotation(FieldMapping.class); System.out.println(fieldStuName.name()+"--"+fieldStuName.type()+"--"+fieldStuName.length()); FieldstuAge=clazz.getDeclaredField("stuAge"); FieldMappingfieldStuAge= stuName.getAnnotation(FieldMapping.class); System.out.println(fieldStuAge.name()+"--"+fieldStuAge.type()+"--"+fieldStuAge.length()); //通过上面查询到的数据拼接成SQL语句 Stringname="果冻"; Stringsql= "select*from"+tbStudent.value()+"where"+fieldStuName.name()+"='"+name+"'"; System.out.println("SQL="+sql); }catch(Exceptione){ //Handletheexception } } }
通过上面的代码,有木有感受到自定义注解还是非常简单的;同时有没有感觉到注解这个功能是非常强大的。
总结
总的来说,注解这个功能很强大,但是使用起来确是非常简单的,这就是牛叉东西的特点,好用又让人不感觉到复杂。以后再遇到注解东西,内心就不再犯怵,不再迷茫了。
以上就是Java注解学习笔记的详细内容,更多关于Java注解的资料请关注毛票票其它相关文章!