Java 反射知识点补充


前言

Java 反射解析
补充一手和反射有关的知识点,随缘更新


一、通过反射越过泛型检查

Java为了向下兼容,提出来的泛型只是一个语法糖,并不是真正的泛型,通过反射,我们可以越过泛型检查。
因为在编译时期Vava会对泛型进行检查。但是当类被转化为字节码文件( .class)时候(运行时期,没有泛型),泛型就被擦除了,也就没有了泛型检查。

代码实现

public static void main(String[] args) throws Exception, Exception {
		 ArrayList<Integer> arrayList = new ArrayList<>();
		 arrayList.add(1);
		 arrayList.add(2);
		 arrayList.add(3);
		 System.out.println(arrayList); // 输出:  [1, 2, 3]
		 
		 Class clazz = arrayList.getClass();
		 Method  m = clazz.getMethod("add",Object.class );
		 
		 m.invoke(arrayList, "String");
		 
		 System.out.println("反射后的结果:"+arrayList); //输出: 反射后的结果:[1, 2, 3, String]
	}
}

但是不能使用get,通过反射添加的数据会因为无法通过其强制类型转换而报错

public class TT {
    public static void main(String[] args)  throws Exception{
        Map<String, String> map = new HashMap<>();
        String key = "key";
        Integer val = Integer.valueOf(1);
        Method m = HashMap.class.getDeclaredMethod("put", new Class[]{Object.class, Object.class});
        m.invoke(map, key, val);
        System.out.println(map); 
        //但是下面的输出会报错
        System.out.println(map.get(key)); 
     }
}

控制台报错:

{key=1}
Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
	at TT.main(TT.java:26)

二、反射+注解控制执行main类

代码实现

反射类

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

@Pro(className = "ReflectTest", methodName = "main")
public class Test {
    public static void main(String[] args) throws Exception {
        //1.通过当前类的字节码对象,判断当前类上是否有自定义的Pro注解
        Class reflectTestClass = Test.class;
        //2.有的话,获取该自定义注解,并生成对象
        if (reflectTestClass.isAnnotationPresent(Pro.class)) {
            Annotation annotation = reflectTestClass.getAnnotation(Pro.class);
            Pro pro = (Pro) annotation;// 自定义注解都继承自父接口Annotation,用多态的方式获得Annotation对象后,需要向下转型为自定义的注解类型Pro的对象
            //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]);
        }
    }
}

注解类

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();
}

实验类

public class ReflectTest {
    public static void main(String[] args) {
        System.out.println("调用ReflectTest类main方法");
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值