亲宝软件园·资讯

展开

Java 注解 So Easy!!!

~小黑 人气:2
# Java注解 ``` Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate. Java 注解是一种元数据,(元数据,用来描述数据的数据,主要其描述作用,让数据变得有具体的作用),注解对程序提供一些数据,但不是程序的部分.注解不能直接影响所标注的代码. ``` 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。 ``` 注解有许多用处,主要如下: 提供信息给编译器(Information for the compiler): 编译器可以利用注解来探测错误和警告信息 编译阶段时的处理(Compile-time and deployment-time processing ): 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。 运行时的处理(Runtime processing): 某些注解可以在程序运行的时候被检测到 值得注意的是,注解不是代码本身的一部分。 ``` ## 一. 注解的基础 利用IDE自动生成重写父类或者接口的方法时,都会生成如下的格式: ```java @Override void mySuperMethod() { ... } ``` 其中`@Override`就是一个简单的注解 @暗示编译器这是一个注解. 同样注释也可以拥有属性,例如: ```java @Author( name = "Benjamin Franklin", date = "3/27/2003" ) class MyClass() { ... } ``` 如果只有一个属性,可以省略`=`和属性名 ```java @SuppressWarnings(value = "unchecked") void myMethod() { ... } //等效的 @SuppressWarnings("unchecked") void myMethod() { ... } ``` 如果注解没有属性,那么括号也可以省略 ``` @Author(name = "Jane Doe") @Author(name = "John Smith") @EBook class MyClass { ... } ``` 细心的读者可能发现.这里使用了两个`@Author`.通常注解只能是一个,在JKD1.8出现了可重复注解 **在哪里使用注解 :** 在JDK 1.8之前, 注解只能使用在声明地方,例如类的声明,方法的声明,属性的声明的地方.通常的约定是注解独占一行.在JDK 1.8之后,注解可以出现在使用类型的地方 + 创建一个对象时: ```java new @Interned MyObject(); ``` + 类型转换 ```java myString = (@NonNull String) str; ``` + 抛出异常时: ```java void monitorTemperature() throws @Critical TemperatureException { ... } ``` 上面的这种用法叫做`类型注解`,可以在任何使用类型的地方使用.类型可以包括(类,属性,方法,定义的常量).这是JDK 1.8 更新的内容,同时更新的还有可重复注解 ## 二.如何创建一个注解 注解通过 @interface 关键字进行定义。它的形式跟接口很类似,不过前面多了一个 @ 符号。上面的代码就创建了一个名字为 TestAnnotaion 的注解。 ```java public @interface TestAnnotation { } ``` 使用自定义注解 ```java @TestAnnotation public class Test { } ``` 创建带有属性的注解 ```java @interface ClassPreamble { String author(); String date(); int currentRevision() default 1; String lastModified() default "N/A"; String lastModifiedBy() default "N/A"; // Note use of array //在这里使用了数组作为属性 String[] reviewers(); } ``` ```java @ClassPreamble ( author = "John Doe", date = "3/17/2002", currentRevision = 6, lastModified = "4/12/2004", lastModifiedBy = "Jane Doe", // Note array notation //数组在注解的使用方法 reviewers = {"Alice", "Bob", "Cindy"} ) public class Generation3List extends Generation2List { // class code goes here } ``` ## 三.可重复的注解: 这是JDK1.8 的更新. 例如: 如果你写了一个方法,需要在不同的时间执行,例如像UNIX的定时任务.那么我们可以利用注解`@Schedule`来表明方法执行的会时间 . ```java @Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... } ``` 它的创建需要两个部分 + 定义一个可以重复的注解 ```java import java.lang.annotation.Repeatable; @Repeatable(Schedules.class) //不要忘记.class public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; } ``` + 声明一个重复注解类型的容器 ```java public @interface Schedules { Schedule[] value(); } ``` 什么是容器注解呢?就是用来存放其它注解的地方。它本身也是一个注解。 按照规定,它里面必须该容器要有一个 value 的属性,属性类型是一个被 @Repeatable 注解过的注解数组,注意它是数组。 ## 四. Java语言预定义的注解(Predefined Annotation Types 在Java API中提前 定义了一些注解,这些注解有的被编译器使用(例如@Overrider),有的被其他注解使用 ,被其他注解使用的有 `@Retention` `@Document` `@Target` `@Inherited` `@Repeatable`5种 ### @Retention @Retention 应用到一个注解上的时候,它解释说明了这个注解的的生命周期。 它的取值如下: + RetentionPolicy.SOURCE : 注解只在源代码阶段保留,在编译器编译时将忽略它 + RetentionPolicy.CLASS : 注解只在编译阶段存在,不会加载到JVM中 + RetentionPolicy.RUNTIME :注解可以保留到程序运行,在程序运行时可以获取到他们 1. @DOCument 这个注解表示能够将注解中的元素包含到Javadoc中. 2. @Target @Target 表示注解运用的地方 ,限定注解使用的地方 + ElementType.ANNOATION_TYPE 可以给一个注解 进行注解 + ElementType.CONSTRUCTOR 可以给构造器注解 + ElementType.FIELD 可以给竖向进行注解 + ElementType.LOCAL_VARIABLE 可以给局部局部变量注解 + ElementType.METHOD 可以给方法注解 + ElemntType.PACKAGE 可以给包注解 + ElementType.PARMETER 可以给一个方法内的参数进行注解 + ElementType.TYPE 可以给一个类型进行注解,比如类,接口,枚举 3. @Inherited Inherited 是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了父类的注解。 ## 五 类型注解 Java8 为 ElementType 枚举增加了TYPE_PARAMETER、TYPE_USE两个枚举值,从而可以使用 @Target(ElementType_TYPE_USE) 修饰注解定义,这种注解被称为类型注解,可以用在任何使用到类型的地方。 在 java8 以前,注解只能用在各种程序元素(定义类、定义接口、定义方法、定义成员变量…)上。从 java8 开始,类型注解可以用在任何使用到类型的地方。 TYPE_PARAMETER:表示该注解能写在类型参数的声明语句中。 类型参数声明如: TYPE_USE:表示注解可以再任何用到类型的地方使用,比如允许在如下位置使用: + 创建对象(用 new 关键字创建) + 类型转换 + 使用 implements 实现接口 + 使用 throws 声明抛出异常 ```java @Target(ElementType.TYPE_USE) @interface NotNull{ } // 定义类时使用 // 在implements时使用 @NotNull public class TypeAnnotationTest implements Serializable { // 在方法形参中使用 // 在throws时使用 public static void main(@NotNull String [] args) throws @NotNull FileNotFoundException { Object obj = "fkjava.org"; // 使用强制类型转换时使用 String str = (@NotNull String) obj; // 创建对象时使用 Object win = new (@NotNull) JFrame("疯狂软件"); } // 泛型中使用 public void foo(List<@NotNull String> info) { } } ``` 这种类型注解,可以让编译器执行更严格的代码检查,从而提高程序的健壮性。 java8本身并没有提供这种注解的框架,要想这些注解发挥作用,需要开发者自己实现,或者使用第三方提供的工具 这里提供一个第三方框架[ Checker Framework](https://checkerframework.org/),如果感兴趣的话可以看一看.

加载全部内容

相关教程
猜你喜欢
用户评论