基础加强:注解
来源:互联网 发布:男性特点知乎 编辑:程序博客网 时间:2024/06/05 09:23
1)所有的注解类型都继承了java.lang.annotation.Annotation这个公共接口 (接口的继承性),说所有注解类型是继承而不是实现,说明所有注解的类型本质就是接口。源码如下:
2)注解通常单独放置在一行,不影响程序代码的执行。无论是增加或者删除注解,代码都始终执行。public interface Annotation { boolean equals(Object obj); int hashCode(); String toString(); Class<? extendsAnnotation> annotationType();}
- 限定重写:@Override
- 标记过时:@Deprecated
- 抑制警告:@Suppresswarning
- 三种内建注解都被@Retention和@Target来修饰,@Deprecated又被@Documented修饰,可以被javadoc来是识别
- 三种内建注解只有@Deprecated的生命周期被保留到内存字节码阶段,其余三种的生命周期是Java源文件阶段。
- 只有@SuppressWarnings这个注解有一个value的属性变量,是字符串数组类型的。
package java.lang.annotation;public enum ElementType { TYPE, FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE}
- TYPE:类类型、接口类型 (注解类型)、枚举类型声明
- FIELD:成员属性声明 (包括枚举常量成员)
- METHOD:成员方法声明
- PARAMETER:参数声明
- CONSTRUCTOR:构造方法声明
- LOCAL_VARIABLE:局部变量声明
- ANNOTATION_TYPE:注解类型声明
- PACKAEG:包声明
package java.lang.annotation;public enum RetentionPolicy { SOURCE, CLASS, RUNTIME}
SOURCE:表示被修饰的注解的生命周期持续到源文件阶段,被Javac编译完成之后就丢弃
CLASS:成员属性声明 (包括枚举常量),被@Retention修饰的注解被Javac编译完成之后会保留,在字节码被JVM运行时丢 弃。注意:@Retention的value的默认取值就是RetentionPolicy.CLASS。
RUNTIME:成员方法声明,被@RUNTIME修饰的注解一直被保留到JVM运行时。
- 对于@Documented、@Retention和@Target可以相互修饰也可以修饰自身。
- @Inherited也被其他三种元注解修饰,但是他不修饰其他元注解,也不修饰自身。
- 四种元注解的生命周期都是到内存字节码阶段。四种元注解的修饰范围只能是注解,不能修饰非注解元素。
- 四种元注解都能被javadoc工具识别并提取成文档。
(2)访问时,以成员变量的形式来进行访问。
3)为注解添加属性//定义时
public @interface MyAnnotation{
String name();
}
//访问时
@MyAnnotation(color="red")
在其他类上使用这个注解,name属性不指定初始值(因为在注解类定义的时候,已经为这个成员变量设置了默认值),但是age必须制定初始值,因为接口中的方法必须被实现。不过在使用该注解时可以根据需要设置新的属性覆盖掉默认值。如下:@interface MyAnnotation{ String name() default "Mike"; int age();}
(2)调用注解时省略变量名的情况@MyAnnotation(name="John", age=18)public class AnnotationTest{}
- 当注解的定义中只有一个抽象方法且方法名为value的时候,可以在调用这个注解的时候省去变量名,直接赋值。如果这个方法名不是value的话,会报错并提示"Creat attribute value()"。如下:
- 如果注解定义中有多个方法,但是除了一个value()以外,其他方法全部都有默认值,此时也可以直接对value()进行赋值。
4)为注解增加高级属性package cn.itheima;@interface AnnotationOne{String color() default "red";int value();}@AnnotationOne(100)public class MyAnnotation {public static void main(String[] args) {// TODO Auto-generated method stub}}
注意:注解中数组设置默认值和调用的时候,仅接受“{ }”定义的初始值,不接受new关键字声明的数组。否则编译错误。//定义含有数组属性的注解
@interface AnnotationArray { int[] arr() default {4, 5, 6};}
//调用该注解并为注解赋新值@AnnotationArray(arr ={1, 2, 3})class AnnotationArrayTest{}//利用反射测试新值是否赋值成功@AnnotationArray(arr={1,2,3})public class MyAnnotation {public static void main(String[] args) { if(MyAnnotation.class.isAnnotationPresent(AnnotationArray.class)){ AnnotationArray AnArr =(AnnotationArray)MyAnnotation.class .getAnnotation(AnnotationArray.class);printArr(AnArr.arr());}}public static void printArr(int[] arr){for (int i : arr) {System.out.println(i);}}}//输出结果:1 23 赋值成功。
(3)为注解增加注解属性package cn.itheima;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;// 自定义Gender枚举类型enum Gender{ male(1), female(0); private int genderIndex =-1; private Gender(int genderIndex){ this.genderIndex =genderIndex; }}
//为注解设定生命周期,便于反射调用@Retention(value=RetentionPolicy.RUNTIME)
//自定义含有Gender枚举类型的注解类型@interface AnnotationEnum{ Gender gender() default Gender.male;}
//调用这个含有枚举类型的属性的注解类@AnnotationEnum(gender =Gender.female)public class MyAnnotation2 { public static void main(String[] args) {if(MyAnnotation2.class.isAnnotationPresent(AnnotationEnum.class)){ AnnotationEnum AnEnum = (AnnotationEnum)MyAnnotation2.class.getAnnotation(AnnotationEnum.class);System.out.println(AnEnum);}}}
4)反射操作注解对象package cn.itheima;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;enum Gender{ male, female;}
@interface AnnotationEnum{ Gender gender() default Gender.male;}
//为注解设定生命周期,便于反射调用@Retention(value=RetentionPolicy.RUNTIME)
//使用这个AnnotationAnno作为另一个注解中的成员变量@interface AnnotationAnno{AnnotationEnum anEnum () default @AnnotationEnum(gender =Gender.female);//注意写法,@不能丢。}
//调用这个含有注解类型的属性的注解类@AnnotationAnno()public class MyAnnotation2 { public static void main(String[] args) { if(MyAnnotation2.class.isAnnotationPresent(AnnotationAnno.class)){AnnotationAnno AnAnuo = (AnnotationAnno)MyAnnotation2.class.getAnnotation(AnnotationAnno.class);System.out.println(AnAnuo);}}}
AnnotatedElement接口专门用于使用反射操作注解, 已知实现子类:AccessibleObject , Class, Package
由于注解是一种标记,仅仅是用来修饰其他程序元素的,因此注解不能单独使用,要依附于具体的程序元素才能使用。所以,让相应的程序片段对应的反射的类(AccessibleObject,Constructor, Filed, Method, Class, Package)去实现AnnotatedElement接口表示这些类的对象通过自身就有能力用反射来来判断自身(程序元素)是否含有注解。
(2)常见操作
- 判定是否存在某一种指定类型的注解
- 获取指定类型的注解对象
- 返回出现在这个程序元素上所有的注解(直接或者间接的都算)
- 返回直接出现在这个程序元素上所有的注解(间接的不算)
注意:使用反射的操作注解的时候,这个注解的生命周期一定要到运行时期。需要对这个注解用元注解@Retention进行修饰,并且把@Retention的成员属性value的值设定为RetentionPolicy.RUNTIME。否则,由于注解默认的是维持到字节码阶段。这样在装载.class文件的时候,这些注解就要被去掉,反射技术无法访问到这些字节码文件注解。
- (32)基础加强&注解
- 基础加强:注解
- 基础加强- 注解(Annotation)
- JAVA基础加强:注解
- java基础加强2--注解
- Java基础加强---Annotation(注解)
- 基础加强_注解Annotation
- 基础加强—注解(Annotation)
- 基础加强三 注解 泛型
- java基础加强05 注解
- 黑马程序员基础加强---注解
- 《黑马程序员》基础加强---注解
- (20)基础加强-内省-注解
- JAVA基础加强之注解
- 黑马程序员 基础加强 注解
- java基础加强_04_注解
- JAVA基础加强_注解
- 黑马程序员--基础加强注解
- java 线程同步
- 数字雨C++代码(转)
- Day3:菱形的做法(会不会太麻烦了呢?)
- Hibernate之Mysql数据库配置文件代码
- linux screen 命令详解
- 基础加强:注解
- C#中写xml 头部定义
- sql查询表中根据某列排序的任意行
- 第三章 数组和字符串
- 实施hadoop大集群(一)
- asp.net调试JS脚本
- c编程技巧——获取可用的处理器(cpu)核数
- 将字符串转化为tm结构体的数据
- 发给谁