知乎上看到的关于类.class,对象.getClass

复制代码
 1 public class TestDemo {
 2     //测试
 3     @Test
 4     public void fun01() {
 5         TestDemo q=new TestDemo();
 6         A a = new A();
 7         q.adapter(a);
 8     }
 9     
10     private void adapter(Base base){
11                 
12         HashMap<Class<? extends Base>,String> class2methodName=new HashMap<Class<? extends Base>,String>() 
13         {
14             private static final long serialVersionUID = 1L;
15             {
16                 put(A.class,"printA");
17                 put(B.class,"printB");
18             }
19         };
20         System.out.println(class2methodName.get(base.getClass()));
21         invokeMethod(this,class2methodName.get(base.getClass()),new Class<?>[]{Base.class},new Object[]{base});
22     }
23     
24     public void printA(Base base) {
25         A a=(A)base;
26         System.out.println("is A:"+a.num);
27     }
28     public void printB(Base base) {
29         B b=(B)base;
30         System.out.println("is B:"+b.num);
31     }
32     
33     @SuppressWarnings("unchecked")
34     private static <T> T invokeMethod(T obj, String methodName, Class<?>[] classes, Object[] objects) {
35         T val = null;
36         try {
37             Method m = null;
38             if(objects != null && classes != null){
39                 m = obj.getClass().getDeclaredMethod(methodName, classes);
40                 val = (T)m.invoke(obj, objects);
41             }else{
42                 m = obj.getClass().getDeclaredMethod(methodName);
43                 val = (T)m.invoke(obj);
44             }
45         } catch (Exception e) {
46             e.printStackTrace();
47         }
48         return val;
49     }
50 
51     private class Base{
52         public int num = 1;
53     }
54     
55     private class A extends Base{
56         public int num = 2;
57     }
58     
59     private class B extends Base{
60         public int num = 3;
61     }
62 }
复制代码

见知乎 : https://www.zhihu.com/question/66705139   也有大佬的点评

上述代码第21行 : 

invokeMethod(this,class2methodName.get(base.getClass()),new Class<?>[]{Base.class},new Object[]{base});
改成:
invokeMethod(this,class2methodName.get(base.getClass()),new Class<?>[]{base.getClass},new Object[]{base});
就会报错,NoSuchMethodException
原因是什么?
  首先看,map中有两个值,一个是{key:运行时类A,value:"printA"}{key:"运行时类B",value:"printB"}
  测试方法中传的是A的对象
  没改的情况 : invokeMethod(testDemo对象,"printA",运行时类A,数组存放的一个A对象)
  改后的情况 : invokeMethod(testDemo对象,"printA",运行时类Base,数组存放的一个A对象)
  
  最后执行的 invokeMethod方法中的,obj.getClass().getDeclaredMethod方法时 会出问题
  
1
2
3
4
public void printA(Base base) {
        A a=(A)base;
        System.out.println("is A:"+a.num);
    }<br>仔细看,此方法 一个参数Base base,反射的invoke方法要求我们必须是Base对象..

  

 
posted @   李勇888  阅读(427)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示