反射 注解的解析

自定义注解 (只可以解析RUNTIME的才有效果)

  1. 只有一个成员的注解
public @interface Description{
    String desc();
}
@Description(desc="the name method")

不会报错。 但不符合规范,既然只有一个成员,就要使用value作为成员名,改成:

public @interface Description{
    String value();
}

然后在使用注解的时候,直接赋值,不写成员名和等号:

@Description("the name method")

以上方式,约定俗成,比较直观。

  1. 没有成员的注解——标志注解(比如常见的@Override),在使用的时候不加括号。
  2. 当一个方法被规定为({ElementType.METHOD})就表示只能用于方法的注解,如果用在类上面,就会报错(添加 ElementType.TYPE 则可适用于类)。这里没有包含关系,例如只写ElementType.TYPE 则不能对方法进行注解,只能对类或接口进行注解。
  3. @Documented(属于标识注解,生成javadoc时会包含注解) 创建一个Javadoc :右击项目--> Export --> Java --> Javadoc --> next -->Browser 选择要存放的文件夹。点击finish就生成成功了。 打开这个文件夹,点击index.html,就能查看该项目的一些摘要。
package com.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME)
@Inherited 
@Documented

public @interface Boy {
    //public String name(String name);//这是错误的
    //注解的方法不可带参数
    //注解的方法叫做成员
    public String name();
    //public Object jump();
    //注解方法返回值类型限定为:基本类型、String、Enums、Annotation或者是这些类型的数组;
    public int  jump();
    //注解方法可以有默认值;
    public int age() default 18;
}

使用自定义注解语法

@<注解名>(<成员名1>=<成员的值1>,<成员名2>=<成员的值2>,)

@Boy(name="king",age=20)
public String User(){
    
    return "user";
}

解析注解

概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

isAnnotationPresent() getAnnotation() getAnnotations() 类上的注解,方法上班的注解

1.定义了一个Boy注解

package com.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME)
@Inherited 
@Documented
public @interface Boy {
    public String name();
    public int age() default 18;
}


定义了一个使用Boy注解的Student

package com.test;

@Boy(name="king",age=20)
public class Student {
    
    @Boy(name="kk",age=25)
    public String user() {
        
        return "ddd";
    }
}

解析Student上的boy注解

package com.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {

    public static void main(String[] args) throws ClassNotFoundException {
        
        //1.使用类加载器加载类
    
        Class c = Class.forName("com.test.Student");
        //2.找到类上的注解
        boolean isExist = c.isAnnotationPresent(Boy.class);
        
        if(isExist){ 
        //3.拿到注解实例
        Boy d = (Boy)c.getAnnotation(Boy.class);
        //访问直接成员的值
        System.out.println(d.name());
        System.out.println(d.age());
        }
        
        //4.找到方法上的注解
        Method[] ms = c.getMethods();
        for(Method m:ms){
                boolean isMExist = m.isAnnotationPresent(Boy.class);
                if(isMExist){
                    Boy d = m.getAnnotation(Boy.class);
                    System.out.println(d.name());
                    System.out.println(d.age());
                }
         
         }
        
        
    }
}

getAnnotations()

for(Method m:ms){
Annotation[] as = m.getAnnotations();
for(Annotation a:as){
if(a instanceof Boy){
Boy d = (Boy)a;
 System.out.println(d.name());
 System.out.println(d.age());
}

@Inherited

如果子类继承 只会继承class上的注解,不会继承方法上的注解

转载于:https://my.oschina.net/2016jyh/blog/1789102

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值