通过反射和注解的方式执行其他类的main方法

通过反射和注解的方式执行其他类的main方法

在上一篇《通过反射和配置文件的方式执行其他类的main方法》中,用的是配置文件来指定的全限定类名和方法名,本篇采用的是用注解来指定全限定类名和方法名。

1.准备工作
  • 被调用main()方法的其他类Calcalator.java
  • 自定义注解类Pro.java
  • 反射所在的类ReflectTest.java

如下图
在这里插入图片描述

最终达到效果依然是,运行ReflectTest类时,Calcalator类的main()方法也被执行了。

2.过程
(1)Calculator类

Calculator.java的main()的方法只有简单一句输出,来检验main()方法被执行了即可。下附代码如下:

package afu.day20200919;

public class Calculator {
    public static void main(String[] args) {
        System.out.println("Calculator的main()方法执行了");
    }
}
(2)自定义注解Pro.java
自定义注解Pro.java文件包含几个部分:
①元注解@Target,用来指明@Pro可以用在那些地方
(TYPE类,METHOD方法,FIELD成员变量)
②元注解@Retention,用来指明@Pro可以保留到哪一阶段
(SOURCE源码,CLASS编译期,RUNTIME运行期)
③抽象方法。
   实际上可理解为成员变量。方法名就是成员变量名,方法的返回值就是成员变量的取值。

所以,当我们有一个Pro注解的对象pro之后,直接用pro.className和pro.methodName就能得到注解上记录的对应值“day12.Calculator”和“main”。
下附代码如下:

package afu.day20200919;

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

@Target(value = {ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Pro {
    String className();
    String methodName();
}
(3)ReflectTest类

ReflectTest类,反射来获取自定义注解的对象。下附代码如下,执行就完事儿。

package afu.day20200919;

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

@Pro(className = "day12.Calculator", methodName = "main")
public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //1.通过当前类的字节码对象,判断当前类上是否有自定义的Pro注解
        Class reflectTestClass = ReflectTest.class;
        //2.有的话,获取该自定义注解,并生成对象
        if (reflectTestClass.isAnnotationPresent(Pro.class)) {
            Annotation annotation = reflectTestClass.getAnnotation(Pro.class);
            Pro pro = (Pro) annotation;
            //3.通过该注解对象,获取注解的内容className和methodName
            String className = pro.className();
            String methodName = pro.methodName();
            //4.根据全类名className获取对应类字节码对象
            Class clazz = Class.forName(className);
            //5.根据该字节码对象获取指定方法methodName的Method对象
            Method method = clazz.getMethod(methodName, String[].class);
            //6.通过Method对象执行该方法
            method.invoke(clazz.newInstance(), (Object) new String[5]);
        }
    }
}

酱!!!

3.注意

(1) 自定义注解
自定义注解本质上就是接口interface。可以通过反编译命令来查看。

javac Pro.java
javap Pro.class

在这里插入图片描述
另外,自定义注解都继承自父接口Annotation,用多态的方式获得Annotation对象后,需要向下转型为我们自定义的注解类型Pro的对象,即:

Pro pro = (Pro) annotation;

因为,父引用不能直接调用子类型特有的成员变量和方法。
String className();和String methodName()是我们自定义的,父接口中Annotation肯定是没有的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值