注解Annotation 很重要! 1注解是一种独立类型,和类和enum都是同等地位,本质也是类。用@interface定义注解类,都会自动继承java.lang.annotation.Annotation接口。2一旦用注解@ MyAnnotation就相当于生成MyAnnotation注解类的对象 3与配置文件功能一样,但都要掌握!4注解可以定义在包上 ,类上,方法上,属性上,方法参数上,方法局部变量上,java内置注解都在java.lang包里,要掌握注解的原理,而不是只会用!
1JDK提供的三个注解:
1Override注解:
在编译期消除重写的错误:如写成toSting。这类错误很难去排除。Orverride注解预示着,该方法必须是重写父类的方法,一旦写错 会报编译错误!
@Override
public String toString()
2Deprecated注解
对类升级后,一个方法感觉写的不好,不想再用了,但也不想让其他人使用我类库的人出错,让心的人不要再用,就用在方法上加@Deprecated注解
类的方法一旦加上Deprecated注解,表明方法被遗弃了,不推荐使用,一旦使用会提示信息
3 SuppressWarning注解 取消编译时警告提示,以及提示 数组类型的属性value??
jdk5一旦不使用泛型会报警告,可以在不使用泛型的方法上甚至main方法上加
@SuppressWarning(“unchecked”) 不查泛型。
@SuppressWarning(“deprecation”)不提示方法过时
元注解:注解的注解
1注解生命周期:1源文件 2.class文件 3内存中的字节码 在1转到2 2转到3时都有可能将注解除去。
用Retention注解可以定义注解生命周期:1 RetentionPolicy .SOURCE 2
RetentionPolicy.CLASS (默认值)3 RetentionPolicy.RUNTIME
Retention是元注解:注解的注解
所有注解都会被@Retention注解修饰!!!!如:@Override是SOURCE
RetentionPolicy是个枚举,有三个取值
例子:
1//自定义注解,将注解MyAnnotation保留到内存字节码里,这样可以通过反射获取注解信息!
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{ }
2一个含有自定义注解MyAnnotation的类Test:
//判断类上是否有注解(只是类上?),有的话获得注解,还要强制转化!
@ MyAnnotation
class Test{
main(){
//是否存在,存在获得注解对象
if(Test.class.isAnnotationPresent(MyAnnotation.class)){
MyAnnotation ma= (MyAnnotation)Test.class.getAnnotation(MyAnnotation.class);
}
2注解位置:Target注解指定注解位置, ElementType[]枚举数组属性可以接受多个枚举值,
ElementType.TYPE类型注解,可以定义在类上,接口上,枚举上
ElementType.Method 方法注解,只能在方法上!
Field
PARAMETER等等 去查ElementType枚举
@Target(ElementType.Method)方法的注解,@Target({ElementType.Method ,ElementType.TYPE })
@Target(ElementType.)
public @interface MyAnnotation{ }
2定义注解属性
为属性定义默认值时,用注解修饰时可以不去写属性,但会默认将属性写上并赋值默认值!不定义属性时,必须显示为属性设值
1 public @interface Text{String value();} 定义方法,实质是public static方法,当做属性用!
用法:
@Test(value=“hello”)或@Test(“hello”)当注解属性名是value且只需设置一个value属性时可以省略属性名,其他名称,或还需要同时设置其他属性时不可省。但如果属性没有默认值,就必须要给属性显示赋值!
如果属性有默认值
@interface Text{String value() default “hello”;}有默认值,可以不赋值@Test()
2注解数组类型属性
public @interface Text{ String value();int[] array() default {4,3,5} ;}
用法:@ Text(value=”3”,array={7,5,9})
当@ Text(value=”3”,array=7) 当数组属性只有一个值,不用加{}
如果是枚举数组:@Target({ElementType.Method ,ElementType.TYPE })
3 注解枚举类型属性
enum Enumset{Hello,World,Welcome;}
public @interface Text{String value();EnumeSet word() default Enumset.Hello;}
用:@Test(value2=Enumset.Welcome)或@Test(value=“额”,value2=Enumset.Welcome)
4 注解注解类型属性
@ MyAnnotation()就是生成注解对象!
public @interface Text{ String value();MyAnnotation ma() default @ MyAnnotation();}
使用;
@Test(value=“额”,ma=@ MyAnnotation(value=”ee”))
4也可以是Class类型属性
5 还可以是上面的数组
3读取注解属性信息:
@ Text(value=”3”;array={7,5,9},;EnumeSet word() default Enumset.Hello;
MyAnnotation ma() default @ MyAnnotation()
)
class Test{
main(){
//是否存在,存在获得注解对象
if(Test.class.isAnnotationPresent(Text.class)){
Text test= (Text)Test.class.getAnnotation(Text.class);
//用annotation对象调用的方法,获取属性
test.value(); 返回String
test.array(); 返回int[]
test. word(); 返回枚举对象
test.ma().value(); 又返回个注解对象,还可以调方法
}
3注解里可以定义数组类型的属性
public @interface Text{String []value3();} 用:@Test(value3={“阿杜”,“额外发违法”})
当只赋一个值可以去掉{}:@Test(value3=“阿杜”)
4编译一个java文件时,默认会将注解信息也留在class文件中,但不能被JVM所读取。
这种控制是java.lang.annotation.Retention注解控制,是修饰注解的注解。有value属性类型是RetentionPolicy枚举(注解的保持策略),有三个对象,三种注解保持策略:CLASS(默认),RUNTIME(运行时JVM可以通过反射机制读类的注解信息),SOURCE(不把注解信息加入class文件中)
例子:
new--Annotation
1@Retention(RetentionPolicy.RUNTIME)修饰注解的注解,放在注解定义上
public @interface MyAnnotation{String hello()default “abf”;String world();}
2@MyAnnotation(hello=”n”,world=”ee”)
class Test{
@MyAnnotation(hello=”n”,world=”ee”)
output(){}
}
5用反射读取运行期的注解信息:接上面,RetentionPolicy是RUNTIME,运行时JVM可以通过反射机制读Test类的注解信息,因为:1Class<?> 2Field 3 Constructor 4 Method都实现了AnnotationElement接口,里面有获取注解信息的方法,可直接使用
class MyReader{main(){
Test test=new Test();
Class<Test>class=test.class;
1 获取Test类output方法上的注解信息:
Method method=class.getMethod(“output”,new Class[]{});
if(method.isAnnotationPresent(MyAnnotation.class)){判断类方法是否有特定注解
MyAnnotation my=method.getAnnotation(MyAnnotation.class);获取注解;
String s=my.hello();获取注解的属性!
Annotation[]a=method.getAnnotations();获取方法的所有的Annotation
for(Annotation a1:a){
Class class=a1.annotationType();获得Annotation的Class对象!
String s=class.getName();返回该Annotation的全名
}}}}
6.java.lang.annotation.Target注解:也是修饰注解的注解,定义注解使用??它有value属性是java.lang.annotation.ElementType枚举类型的包括:FIELD METHOD (只能修饰方法)
TYPE(只能修饰类或接口或枚举)
@Target(ElementType.METHOD)
@interface MyTarget{String value();}如果MyTarget放在类上会报错
7.java.lang.annotation.Documented :决定当把类生成帮助文档doc时,是否把该注解也加入帮助文档
1@Documented
@interface MyTarget{String value();}
2class Test{
@MyTarget
public void method(){}当把Test类生成帮助文档doc时,MyTarget注解也加入帮助文档method方法上。
8Annotation继承:默认情况父类Annotataion不被子类继承,但可以用java.lang.annotation.Inherited注解修饰注解,可被继承
@Inherited
@interface MyTarget{String value();}
|