您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
javase第三季学习笔记-注解
发布时间:2017-08-10 16:12:28编辑:雪饮阅读()
认识Annotation
• JDK1.5开始,Java增加了对元数据(即类的组成单元数据)的支持,也就是(Annotation)注解,他是代码里做的特殊标记,这些标记可以在编译,类加载,运行时在不改变原有逻辑的情况下,被读取,并执行相应的处理,通过使用Annotation,程序员可以在源文件中嵌入一些补充的信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。Annotation类似于修饰符一样被使用,可以用于包,类,构造方法,方法,成员变量,参数,局部变量的声明。
• 注意:
• Annotation是一个接口
• java.lang.Annotation接口.
系统定义的三个Annotation
• 在JDK 1.5之后,在系统中提供了三个Annotation,分别是:@Override、@Deprecated、@SuppressWarnings。
• @Override
• 表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示。
• @Deprecated
• 表示的是一个类或方法已经不再建议继续使用了,标记为已过时。
• @SuppressWarnings
• 表示关闭不当的编译器警告信息。
代码示例:
入口AnnotationDemo:
package com.vince.annotation;
public class AnnotationDemo {
//@SuppressWarnings("deprecation")告诉编译器,过时的方法我使用时不要给我提示警告信息
@SuppressWarnings("deprecation")
public static void main(String[] args) {
User user=new User("XB");
user.print();
}
}
用到的类:User
package com.vince.annotation;
public class User {
private String name;
public User(String name){
this.name=name;
}
@Override
//@Override标记的方法必须是实现其父类的方法名,不能为其它方法名
public String toString() {
return "User [name=" + name + "]";
}
@Deprecated
//@Override标记意为该方法已过时,要用该方法也可以,但不建议
public String print() {
return "User [name=" + name + "]";
}
}
自定义Annotation
• 注解应用需要三个步骤:
• (1)编写注解
• (2)在类上应用注解
• (3)对应用了注解的类进行反射操作的类
• 自定义Annotation的语法如下:
• 访问控制权限 @interface Annotation名称{}
• 例如:
• public @interface MyAnnotation {}
n 在Annotation中定义变量
• public @interface MyAnnotation {
• public String name();
• public String info();
• }
• 定义变量后,在调用此Annotation时必须设置变量值。
• @MyAnnotation(name = “XB", info = “WSDR")
• public class Demo {
• }
n 通过default指定变量默认值,
• 有了默认值在使用时可以不设值
• public @interface MyAnnotation {
• public String name() default “XB";
• public String info() default “WSDR";
• }
n 定义一个变量的数组,接收一组参数
• public @interface MyAnnotation {
• public String[] name();
• }
• 使用时指定数组值
• @MyAnnotation(name = { “XB", “XH" })
• public class Demo {
• }
n 使用枚举限制变量取值范围
• public enum Color {
• RED, GREEN, BLUE
• }
• public @interface MyAnnotation {
• public Color color();
• }
Retention和RetentionPolicy
• Annotation要想决定其作用的范围,通过@Retention指定,而Retention指定的范围由ReteiontPolicy决定,RetentionPolicy指定了三种范围:
范围 |
描述 |
public static final RetentionPolicy SOURCE |
在java源程序中存在 |
public static final RetentionPolicy CLASS |
在java生成的class中存在 |
public static final RetentionPolicy RUNTIME |
在java运行的时候存在 |
• 示列:
• @Retention(value = RetentionPolicy.RUNTIME)
• public @interface MyAnnotation {
• public String name();
• }
反射与Annotation
• 一个Annotation真正起作用,必须结合反射机制,在反射中提供了以下的操作方法:java.lang.reflect.AccessibleObject
• 示例:
• Class<?> cls = Class.forName(“com.vince.annotation.Test");
• Method met = cls.getMethod(“setName"); // 找到toString()方法
• if (met.isAnnotationPresent(MyAnnotation.class)) {
• MyAnnotation my = (MyAnnotation) met
• .getAnnotation(MyAnnotation.class);
• String name = my.name();
• String info = my.info();
• System.out.println("name = " + name);
• System.out.println("info = " + info);
• }
@Documented注解
• 此注解表示的是文档化,可以在生成doc文档的时候添加注解。
• @Documented
• @Retention(value = RetentionPolicy.RUNTIME)
• public @interface MyAnnotation {
• public String name();
• public String info();
• }
• 可以增加一些DOC注释。
• /**
• * 这个方法是从Object类中覆写而来的
• */
• @MyAnnotation(name = “XB", info = “WSDR")
• public String toString() {
• return "hello";
• }
@Target注解
• @Target注解表示的是一个Annotation的使用范围,例如:之前定义的MyAnnotation可以在任意的位置上使用。
@Inherited注解
• @Inherited表示一个Annotation是否允许被其子类继承下来。
• 示例
• @Inherited
• @Target(value = ElementType.TYPE)
• @Retention(value = RetentionPolicy.RUNTIME)
• public @interface MyAnnotation {
• public String name();
• public String info();
• }
• 使用时允许被其子类所继承。
完整示例代码:
入口程序:
package com.vince.annotation;
import java.lang.annotation.Annotation;
public class AnnotationDemo {
//在eclipse中调用一个过时的方法则会出现下划黄色波浪线
//而@SuppressWarnings("deprecation")则是告诉编辑器,我们非要用它,
//不用给我们提示警告信息
@SuppressWarnings("deprecation")
public static void main(String[] args) throws Exception {
User user=new User("XB");
//调用一个被注解为过时的方法
user.print();
//通过反射解析注解
Class<?> c=Class.forName("com.vince.annotation.User");
//获取类标记的所有注解
Annotation[] annotations=c.getAnnotations();
//输出结果解析:
/*
由于User中注解为:@MyAnnotation(name="XB",info="WXDR",like={"杜敏捷","love","雪饮"},sex=EnumSex.GG)
即name,info,like,sex而User类中却仅有name属性,所以如下结果才只输出了name
并且输出的name属性值为注解中name的值
*/
/*
要想遍历注解,则需要将注解的范围设置为RUNTIME,因为只有RUNTIME才是运行期的。
SOURCE只是源代码期,所以到了运行期注解就会丢失的。
*/
System.out.println("---遍历注解---");
for (Annotation a : annotations) {
System.out.println(a);
System.out.println("当前注解信息:"+a.getClass());
//判断当前注解是否是指定注解,。如果是则转换为指定类
if(c.isAnnotationPresent(MyAnnotation.class)){
MyAnnotation ma=(MyAnnotation)a;
String name=ma.name();
System.out.println(name);
}
}
}
}
用到的user类:
package com.vince.annotation;
//使用自定义注解
//注解可以放在类上属性、方法、构造器
//@MyAnnotation 注解中若有属性则不能直接@MyAnnotation这样使用,需要对属性赋值
//如果属性有默认值则无需赋值
@MyAnnotation(name="XB",info="WXDR",like={"杜敏捷","love","雪饮"},sex=EnumSex.GG)
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
//参数上使用注解
public void setName(@MyAnnotation(name="XB",info="WXDR",like={"杜敏捷","love","雪饮"},sex=EnumSex.GG)String name) {
this.name = name;
}
//@Override表示该方法必须是父类的实现方法
@Override
public String toString() {
return "my name is"+name;
}
//@Deprecated标记该方法已过时
@Deprecated
public void print(){
System.out.println("name="+name);
}
}
用到的自定义注解:
package com.vince.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//自定义一个注解
//@Documented此注解表示的是文档化,可以在生成doc文档的时候添加注解。
@Documented
//@Target(ElementType.xxx)表示标注的该标注的使用范围
//如果要指定多个范围形如@Target({ElementType.xxx,ElementType.xxx})
//若不写范围则是在任意地方可以使用
/*
TYPE只能在类或接口或枚举上使用
FIELD在成员变量使用
METHOD在方法中使用
PARAMETER在参数上使用
CONSTRUCTOR在构造中使用
LOCAL_VARIABLE局部变量上使用
NNOTATION_TYPE只能在Annotation中使用
PACKAGE只能在包中使用
*/
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.PARAMETER})
//@Retention(RetentionPolicy.xxx)
//解析:@Retention(RetentionPolicy.xxx)表示注解自身的注解,
//有三种范围SOURCE,表示在在java源程序中存在即代码编写期间的注解
//CLASS在java生成的class中存在即编译期的注解
//RUNTIME在java运行的时候存在,即运行期的注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String name();//定义一个属性
public String info();//定义一个属性
public String info2() default "WSDR";//给属性默认值
public String[] like();//定义一个数组属性
public EnumSex sex();//定义一个枚举属性
}
用到的枚举:
package com.vince.annotation;
public enum EnumSex {MM,GG}
关键字词:javase,注解