- 注释:给程序员看的,用于解释说明程序的功能
- 注解:给程序看的,用于标识程序的运行状态。
一、注解的作用
注解是servlet3.0以后的特性,建议用注解代替XML配置文件,注解的特点及优点有:
- 增强程序的可阅读性,相较于XML,注解紧跟方法,随时修正
- 注解是低耦合的,
把注解应用在反射上,注解与properties配置文件的优势在于:
- 注解可以加注释,而properties文件不可以;
- 注解直接放在方法或类体上,更加直观和便于修改
二、注解的格式
@注解的格式,如:
JDK中提供的注解
JDK中提供的注解有三个,都是给编译器使用的,在编译时期起作用:
@Overrid:放在方法上一行,用于继承中复写方法的声明
在JDK1.5版本中,只能标识由类继承的方法
在JDK1.6版本中,可以标识接口继承的方法@Deprecated:标识已过时的方法
- @SuppressWarnings:压制警告,如SuppressWarnings(”all”)所有警告消除
三、自定义注解
自定义注解,是java的进阶应用。通过注解,并且通过注解合理的应用反射,可以构建简化的代码编写方式
- 通过javap反编译,发现已定义的注解全部都是如下格式的继承方式:
public interface MyAno extends java.lang.annotation.Annotation {}
- 自定义注解格式
public @interface 注解名称{} - 注解中可以定义常量和抽象方法,但是定义常量没有意义,方法就相当于属性(变量);
- 属性:其实就是接口中的抽象方法。注解的属性还可以有默认值,在使用注解时就可以不给带有默认值的属性赋值了。但没有给出默认值的属性还是要赋值的
- 属性的类型
- 基本数据类型
- 字符串类型
- 类类型:Class
- 枚举类型
- 注解类型
- 以上所有的数组类型
public @interface MyAnn {
String value() default "hello world";
int value1();
}
四、元注解
用于说明注解的注解,元注解放在自定义注解的开头,有四个类型,如下:
@Retention : 指定注解信息在哪个阶段存在 Source Class Runtime
- RetentionPolicy.SOURCE:这种类型的Annotations只在源代码级别保留,编译时就会被忽略
- RetentionPolicy.CLASS:这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。
@Retention(RetentionPolicy.RUNTIME) //注解保留到运行时期 @Target({ElementType.TYPE, ElementType.METHOD}) //这是 public @interface MyAnn { String value() default "hello"; int value1() default 100; }
@Target : 指定注解修饰目标对象类型 TYPE 类、接口 FIELD 成员变量 METHOD 方法
public @interface Target {
ElementType[] value();
}
public enum ElementType {
TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE
}
这样MyAnn就只能作用在类和方法上的!其中ElementType.TYPE表示类和接口。
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnn {
}
@MyAnn()
public class MyClass {
@MyAnn()
private int a;
@MyAnn()
public void fun() {}
}
- @Documented :使用该元注解修饰,该注解的信息可以生成到javadoc 文档中
- @Inherited :如果一个注解使用该元注解修改,应用注解目标类的子类都会自动继承该注解
五、解析注解
当注解定义为Runtime阶段,可以使用
当注解定义为Rumtime阶段,可以使用反射的方式获取注解中配置的属性值。在程序运行过程中使用。
步骤:
1.获取字节码文件。
2.获取对象(哪个上边加了注解,获取哪个对象。如果是方法,获取Method对象)
3.获取对象上的注解对象。
4.调用其方法,获取返回值。
//先搞一个自定义注解,要反射一定要定义成RUNTIME
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnn {
String value() default "hello";
int value1() default 100;
}
//把注解应用到相应的类和方法上
@MyAnn(value="hello world", value1=200)
public class MyClass {
private int a;
@MyAnn("myMethod")
public void fun() {}
}
//开始使用了
public class Demo1 {
public static void main(String[] args) throws Exception {
//1.获得字节码文件
Class clazz = MyClass.class;
//2.如果是类的注解,通过getAnnotation()方法
MyAnn myAnn = (MyAnn) clazz.getAnnotation(MyAnn.class);
System.out.println(myAnn.value());
System.out.println(myAnn.value1());
//3.如果是方法的注解,还是通过方法的字节码去获取
Method method = clazz.getMethod("fun");
MyAnn myAnn1 = method.getAnnotation(MyAnn.class);
System.out.println(myAnn1.value());
System.out.println(myAnn1.value1());
}
}

6504

被折叠的 条评论
为什么被折叠?



