注解详解_例子

(1) 定义注解:

package annotations;
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DefineAnnotation {
public String hello() default "aaa";
String world();
}


(2)、使用注解
package annotations;

public class UseDefineAnnotation {
@Deprecated
@DefineAnnotation(hello="ttitfly",world="WORLD!!!")
public void say(){
System.out.println("say hello");
}

/* public static void main(String[] args) {
UseDefineAnnotation tAnnotation=new UseDefineAnnotation();
tAnnotation.say();
}*/
}


(3)、处理器 解析注解
package annotations;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class TestDefineAnnotation {

/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
UseDefineAnnotation useDefineAnnotation=new UseDefineAnnotation();
//1、要解析的方法带有注解的类
Class clazz=UseDefineAnnotation.class;

//Method method = clazz.getMethod("say", null);//因为是无参数的,所以直接写个null也可以
//2、获得带有注解的方法
Method method=clazz.getDeclaredMethod("say", new Class[]{});
method.invoke(useDefineAnnotation, new Class[]{}); //在实例myAnnotation上执行方法method()
//该方法是否使用了MyAnnotation这个注解类
boolean isExists=method.isAnnotationPresent(DefineAnnotation.class);
if(isExists){
//3、获得方法上的注解
/*Annotation在运行时刻,是通过java的动态代理实现的,
每次得到一个annotation,实际上并不是得到该annotation的实例,
而是得到了它的一个代理,这个代理java在命名上采用的是$Proxy1,
$Proxy2...的形式,数字是按照出现的顺序来定的 */
DefineAnnotation annotation=method.getAnnotation(DefineAnnotation.class);
//4、方法注解的element方法
System.out.println(annotation.hello()+" "+annotation.world());
}

System.out.println("-------------------");
/************************************************/
Method[] methods=clazz.getDeclaredMethods();
for(Method mt:methods){
Annotation[] annotations=mt.getAnnotations();
for(Annotation ant:annotations){
System.out.println(ant.annotationType().getName());

//不能通过getClass().getName()的方式获得了。这样获得的结果类似这样的:$Proxy3,主要原因是因为Annotation在运行时刻,是通过java的动态代理实现的,
//每次得到一个annotation,实际上并不是得到该annotation的实例,而是得到了它的一个代理,这个代理java在命名上采用的是$Proxy1,$Proxy2...的形式,数字是按照出现的顺序来定的
//而***getClass()方法返回的是该对象运行时刻所代表的真实对象***,在这里也就是代理对象了
System.out.println(ant.getClass().getName());
//输出结果为:java.lang.reflect.Proxy
System.out.println(ant.getClass().getSuperclass().getName());
}
}
}

}


(4)、注解的继承性 (Inherited)
注解定义时使用了@Inherit,注解用于Type(如class)上时,Type上的注解将被Type的派生类型继承到
package annotations;
import java.lang.annotation.*;

//没有指定@Target(),则注解可用于所有的ElementType
@Inherited
@Retention(RetentionPolicy.RUNTIME)
//在自己定义的Annotation里加入一个@Inherited ,就标识了这个定义的Annotation是可以被继承的
/*指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,
* 同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释
* 或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。

注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。
*/
public @interface MyInherit {
String value();
}

package annotations;

@MyInherit("test class")
public class Parent {
@MyInherit("test method")
public void doSomething(){
System.out.println("hello");
}
}

package annotations;

public class Child extends Parent {

}

package annotations;
import java.lang.reflect.*;

public class TestInherit {

/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
Class< Child > clazz = Child.class;
if(clazz.isAnnotationPresent(MyInherit.class)){
MyInherit myInherit = clazz.getAnnotation(MyInherit.class);
System.out.println(myInherit.value());
}

Method method = clazz.getMethod("doSomething", new Class[]{});
if(method.isAnnotationPresent(MyInherit.class)){
MyInherit myInherit = method.getAnnotation(MyInherit.class);
System.out.println(myInherit.value());
}
}
/*@Inherit指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,
* 同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了
* 该类层次结构的顶层 (Object) 为止. Parent类上使用了注释@MyIherit,Parent的派生类Child将继承类上的注释@MyHerit (这就是@Inherit在@MyInherit上的作用).

注解@MyInherit用于方法Parent.doSomething()上,这个带指定注解@MyInherit的“***方法doSomething()***”
是否可以被Parent的派生类Child所继承到(@MyInherit不管有没有@Inherit,带有注解@MyInherit的方法
doSomething都可以被继承到),方法doSomething确实是被Child{}继承到了,自然方法上的注解是可以被得到的。*/
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值