注解:相当于一个标记,在程序中加了注解,就等于为程序打上了某种标记,没加,则等于没有某种标记。以后,java编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事,标记可以加在包、类、成员变量、方法及方法参数上、局部变量上等。
Jdk自定义的注解:
1. @Deprecated 被@Deprecated标注的对象class, method等被注明为不推荐使用(过期的)。主要用于javac等编译工具。
2. @Override 注明对象method重载了父类的方法。javac等编译工具编译时会根据此Annotation判断重载方法是否正确。
3. @SuppressWarnings 告诉javac等编译器忽略所指定的特定的警告信息。
SuppressWarnings 的源代码:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
SuppressWarnings 参数有:
deprecation:使用了过时的类或方法是的警告
unchecked:执行了未检查的转换时的警告
fallthrough:当switch程序块直接通往下一种情况而没有break时的警告
path:在类路径、源文件路径等中有不存在的路径是的警告
serial:当在可序列化的类上缺少serialversionUID定义是的警告
finally:任何finally子句不能正常完成时的警告
all:关于以上所有情况的警告
4. @Target 被定义的annotation可以附加在那些对象上。
Target的源代码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
它可以接受的参数是枚举类型的ElementType,
ElementType的对象有:
TYPE, //类,接口或者枚举声明
FIELD,//域声明
METHOD,//方法声明
PARAMETER,//参数声明
CONSTRUCTOR,//构造函数声明
LOCAL_VARIABLE,//方法中的本地变量
ANNOTATION_TYPE,//应用于其他注解的元注解
PACKAGE//包声明
5.@Retention 注解的作用期间。
Rentention的源代码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
它可以接受的类型是一个枚举类型的value
RetentionPolicy枚举的对象有:
SOURCE,CLASS,RUNTIME
它们三个作用的期间分别为:.java源文件、.class文件和内存中的字节码
例如@Override和@SuppressWarning注解属性都是属于SOURCE
@Deprecated注解属性RUNTIME
6.@Documented 被此注解标识的代码将包含到javadoc中
7.@Inherited 允许子类继承父类中的注解
注解的属性:
一个注解相当于一个胸牌,如果你的胸前贴了胸牌,就是这个学校的学生,否则就不是;如果还想知道是这个学校的哪个班的学生,这时可以为胸牌再增加属性来区分。如果增加的属性没有缺省值,那么在引用这个注解时要为属性赋值,加了属性的标记效果为:@ItcastAnnotation(color="red");这说明这个注解类中有个属性是color,没有默认值,所以在引用时要为它赋值
1.定义基本类型的属性和应用属性
·在注解类中增加String color();
·引用时:@ItcastAnnotation(color="red")
2.用反射的方式得到注解类对应的实例对象后,再通过该对象调用属性对应的方法
ItcastAnnotation it=Annotation.class.getAnnotation(ItcastAnnotation .class);
下面看实例分析:
有4个.java文件,分别是:要引用的注解类@ItcastAnnotation 、在ItcastAnnotation 注解中再添加一个注解类的属性@MyAnnotation、在ItcastAnnotation 注解中要添加一个枚举类型的属性TrafficLamp(可以参考JAVA之Myeclipse中Junit、静态导入、枚举和单例设计模式)和一个测试用的AnnotationDemo类(具体看代码注释分析)
AnnotationDemo代码:
@ItcastAnnotation(annotation=@MyAnnotation("cccc"),value="aaa")
public class AnnotationDemo {
/**
* @param args
*/
public static void main(String[] args) {
if(AnnotationDemo.class.isAnnotationPresent(ItcastAnnotation.class))
{
//实例化一个注解类的一个对象
ItcastAnnotation it=AnnotationDemo.class.getAnnotation(ItcastAnnotation.class);
System.out.println(it.color());
System.out.println(it.value());
System.out.println(it.arr().length);
//利用it对象取得它的一个属性lamp()(即it.lamp()=RED),lamp()这个属性有默认值RED,利用RED这个实例对象
//的nextLamp()方法取得RED里面的值(即it.lamp().nextLamp())
System.out.println(it.lamp().nextLamp());
System.out.println(it.annotation().value());
}
}
}
ItcastAnnotation代码:
/*
知识点:
1. 如果一个注解类中,只有一个属性,并且是value,那么在运用类中(这里是AnnotationDemo)
为value设置值是可以不用写@ItcastAnnotation(value="aaa"),可以这样写:@ItcastAnnotation("aaa")
举例一:例如Retention这个注解(源代码):
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
它里面只有一个value属性,并且属性的类型是RetentionPolicy,是个枚举:
public enum RetentionPolicy {
SOURCE, CLASS, RUNTIME
}
举例二:例如Target这个注解(源代码):
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
它里面只有一个value属性,并且属性是ElementType[]枚举类型的数组:
public enum ElementType {
TYPE, //类,接口或者枚举声明
FIELD,//域声明
METHOD,//方法声明
PARAMETER,//参数声明
CONSTRUCTOR,//构造函数声明
LOCAL_VARIABLE,//方法中的本地变量
ANNOTATION_TYPE,//应用于其他注解的元注解
PACKAGE//包声明
}
这和"举例一"不一样,Target代表可以取多个ElementType中的多个值,而Retention只能取RetentionPolicy中的一个
我们在运用时就可以直接写RetentionPolicy.SOURCE、RetentionPolicy.CLASS或RetentionPolicy.RUNTIME
2.或者有多个属性(下面的color),如果想达到不写value=“aaa”的形式,那么就要为color属性指定缺省值
* */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface ItcastAnnotation {
//定义一个普通的属性
String color() default "blue";
String value() ;
//定义一个数组
int[] arr() default {1,45,4};
//枚举类型的属性
//定义一个枚举类型的属性,TrafficLamp是一个枚举那么lamp()属性的缺省值就是TrafficLamp的一个实例对象
TrafficLamp lamp() default TrafficLamp.RED;
//注解类型的属性
//MyAnnotation是一个注解,所以它的缺省值就是MyAnnotation的一个实例对象@MyAnnotation
//可是@MyAnnotation中又有一个value属性,没有缺省值,所以要在下面指定
MyAnnotation annotation() default @MyAnnotation("bbbb");
}
MyAnnotation代码:
public @interface MyAnnotation {
String value();
}
TrafficLamp代码:
public enum TrafficLamp {
RED(23){
@Override
public TrafficLamp nextLamp() {
// TODO Auto-generated method stub
return GREEN;
}
},
GREEN(5){
@Override
public TrafficLamp nextLamp() {
// TODO Auto-generated method stub
return YELLOW;
}
},
YELLOW(77){
@Override
public TrafficLamp nextLamp() {
// TODO Auto-generated method stub
return RED;
}
};
public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp(int time){
this.time=time;
}
}