一、注解
注解是什么?注解和注释字面上差不太多,但是注解不是提供代码功能的说明,而是实现程序功能的重要组成部分。注解是java代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。注解是JDK1.5的新特性。
二、基本注解
java为我们提供了三个基本注解,在java.lang包中。分别是用于标注注解的方法是重写父类的方法的@Override注解、用于提醒某个方法或成员变量已经过时的@Deprecated注解和告诉编译器不要显示某些警告的@SuppressWarnings注解。
其中,@Override注解只能用于方法,@Deprecated注解没有要求,@SuppressWarnings注解在使用的时候要传递参数,表示告诉编译器不用显示哪些警告。
@SuppressWarnings注解的参数值有:
depreccation:使用了过时的元素
unchecked:执行了未检查的转换
unused:有程序元素没有被使用
fallthrough:switch程序块直接通往下一种情况而没有break
path:在类路径中有不存在的路径
serial:在可序列化的类上缺少serialVersionUID定义
finally:任何finally子句都不能正常完成
all:所有情况
先创建一个类
public class ItcastAnnotation {
// 表示这个方法已经过时
@Deprecated
public void show(){
System.out.println("---------");
}
// 表示重写Object类的toString方法,@Override只能用于修饰方法
@Override
public String toString() {
return "ItcastAnnotation []";
}
}
然后使用这个类
public class AnnotationTest {
@SuppressWarnings(value="deprecation")
// 这里面value=也是可以省略不写的
public static void main(String[] args) {
new ItcastAnnotation().show(); // 调用已经过的方法该方法上会有一道横线,表示已经过时
}
}
三、自定义注解和元注解
java提供的注解就3个,再不能满足需求的时候,可以使用自定义注解。自定义注解的声明使用@interface。在java中注解的默认存在时间到class文件被加载进内存中就结束,所以要想在程序运行的使用使用注解,就需要使用元注解指定该注解的存活时间。
元注解,就是用于注解注解的注解。有点拗口。java的4种元注解有修饰注解能被用于什么位置的@Target注解、指定注解的存活时间的@Retention注解、想在使用javadoc工具的时候,在生成的帮助文档中也存在注解的@Document注解和想让子类继承父类注解的@Inherited。
@Target注解的常用值:
ElementType.ANNOTATION_TYPE:注解类型声明
ElementType.CONSTRUCTOR:构造方法声明
ElementType.FIELD:字段声明
ElementType.LOCAL_VARIABLE:局部变量声明
ElementType.METHOD:方法声明
ElementType.PACKAGE:包声明
ElementType.PARAMETER:参数声明
ElementType.TYPE:类、接口或枚举声明
@Retention注解的常用值:
RetentionPolicy.CLASS:编译器将注解记录在class文件中,当程序运行时,虚拟机不在保留注解。
RetentionPolicy.RUNTIME:编译器将注解记录在class文件中,当程序运行时,虚拟机保留该注解,可以通过反射获取该注解。
RetentionPolicy.SOURCE:编译在将.java文件编译为.class文件时,将注解直接丢弃。
创建一个自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 创建一个注解,并且添加元注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface SimpleAnnotation {
// 添加简单属性
String name() default "xx"; // default表示属性的默认值
int age(); // 不写default默认值,在使用注解的时候就得写该属性的值
// 添加复杂属性
int[] arr();
LampEnum lamp() default LampEnum.GREEN; // 添加一个枚举
MyAnnotation ma() ; // 添加一个注解
}
创建自定义注解要使用到的枚举
public enum LampEnum {
// 定义枚举成员
RED{
@Override
public LampEnum nextLamp() {
// TODO Auto-generated method stub
return GREEN;
}
}, GREEN{
@Override
public LampEnum nextLamp() {
// TODO Auto-generated method stub
return YELLOW;
}
}, YELLOW{
@Override
public LampEnum nextLamp() {
// TODO Auto-generated method stub
return RED;
}
};
// 私有化构造函数
private LampEnum(){}
public abstract LampEnum nextLamp();
}
创建自定义注解要使用的注解
public @interface MyAnnotation {
String name();
}
通过反射得到注解
// 使用自定义注解
@SimpleAnnotation(name="yy",age=20, ma=@MyAnnotation(name="zz"), arr={2, 5})
public class AnnotationTest {
public static void main(String[] args) {
// 通过反射获得注解
// 判断该类是否有SimpleAnonation注解
if(AnnotationTest.class.isAnnotationPresent(SimpleAnnotation.class)){
// 获取SimpleAnnotion注解
SimpleAnnotation sa = AnnotationTest.class.getAnnotation(SimpleAnnotation.class);
// 打印注解的属性
System.out.println(sa);
System.out.println(sa.name());
System.out.println(sa.age());
System.out.println(sa.arr().length);
System.out.println(sa.lamp().nextLamp());
System.out.println(sa.ma().name());
}
}
}