输出当前 Student类 所属包下面的 被 @AutoRunClass 标注过的类名,并且调用被 @AutoRunMethod 标注过的公开且无参的方法

项目结构

src/com/zzn/reflect

        /annctations

                /AutoRunClass.java

                /AutoRunMethod.java

        /Person.java

        /ReflectDemo

1、创建注解

创建AutoRunClass注解,该注解只用在类上。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoRunClass {

}

 创建AutoRunMethod注解,该注解只用在方法上,并且要设置传递的值。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoRunMethod {
    //设置注解的默认值
    int value() default 1;
}

 

2、创建类,并且添加注解

import com.zzn.reflect.annctations.AutoRunClass;
import com.zzn.reflect.annctations.AutoRunMethod;

@AutoRunClass
public class Person {
    private String name;
    private int age;
    private String sex;

    public Person(){}
    public Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    @AutoRunMethod(value = 5)
    public void sayHello(){
        System.out.println(name+": hello");
    }
}

3、实现:

  1. 输出当前 Student类 所属包下面的 被 @AutoRunClass 标注过的类名。
  2. 调用被 @AutoRunMethod 标注过的公开且无参的方法。
  3. 获取注解的值,根据值设置调用方法的次数
import com.zzn.reflect.annctations.AutoRunClass;
import com.zzn.reflect.annctations.AutoRunMethod;
import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        // 1.定位到 E:\code\JavaCode\JavaBigData\JavaBase\target\classes\com\zzn\reflect
        File dir = new File(Person.class.getResource(".").toURI());
        System.out.println(dir);

        // 2.获取 dir目录下的全部的.class文件
        File[] files = dir.listFiles(f -> f.getName().endsWith(".class"));
        for (File file : files) {
            // 3.获取全限定名
            // 获取类名 Person
            String namePath = file.getName().substring(0, file.getName().indexOf("."));
            //根据 Person这个类的包名 + 类名 来拼接全限定名 com.zzn.reflect.Person
            String className = Person.class.getPackage().getName() + "." + namePath;

            // 4.根据全限定名加载类
            Class cls = Class.forName(className);
            // 5、判断该类是否被标注过,被标记过就进行输出
            boolean annotationPresent = cls.isAnnotationPresent(AutoRunClass.class);
            if (annotationPresent) {
                System.out.println(className + "被标注过了"); //输出被@AutoRunClass 标注过的类名
                Object obj = cls.newInstance();
                
                // 6.获取类里面的全部的方法名
                Method[] methods = cls.getDeclaredMethods();
                for (Method method : methods) {
                    
                    // 7.判断该方法是否被标注过,被标记过就进行输出
                    boolean annotationPresent1 = method.isAnnotationPresent(AutoRunMethod.class);
                    // 调用被 @AutoRunMethod 标注过的公开且无参的方法
                    if (annotationPresent1 & method.getParameterCount() == 0 & method.getModifiers() == Modifier.PUBLIC) {
                        System.out.println(method.getName() + "被标注过了");
                        System.out.println("自动调用方法:" + method.getName() + "()");

                        // 8.获取注解的参数,并调用方法
                        AutoRunMethod annotation = method.getAnnotation(AutoRunMethod.class);
                        int value = annotation.value();
                        for (int i = 0; i < value; i++) {
                            method.invoke(obj);
                        }
                    }
                }
            }
        }
    }
}

扩展:

1、元注解:

@Target() 用于描述注解的使用范围

ElementType.TYPE 表示只能在类或接口上用 
ElementType.FIELD 表示只能在属性上用 
ElementType.LOCAL_VARIABLE 表示只能在局部变量上用 
ElementType.METHOD 表示只能在方法上用 
ElementType.PARAMETER 表示只能在参数上用 
ElementType.CONSTRUCTOR 表示只能在构造器上用 
ElementType.ANNOTATION_TYPE 表示只能在注解上用 
ElementType.PACKAGE 表示只能在包上用 

@Retention() 用于描述当前注解保留的时间长短

RetentionPolicy.SOURCE 在源文件中有效(即源文件保留)

RetentionPolicy.CLASS 在class文件中有效(即class保留)

RetentionPolicy.RUNTIME 在运行时有效(即运行时保留)

2、Class类/Method类/AutoRunMethod类的方法

getParameterCount() 获取方法参数的个数

getModifiers() 获取方法的访问修饰符

isAnnotationPresent() 判断某个类/方法/属性/构造器有没有被某个注解标注过

getAnnotation(AutoRunMethod.class); 获取方法的注解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值