知乎上看到的关于类.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方法时 会出问题
  
public void printA(Base base) {
        A a=(A)base;
        System.out.println("is A:"+a.num);
    }
仔细看,此方法 一个参数Base base,反射的invoke方法要求我们必须是Base对象..

  

 
原文地址:https://www.cnblogs.com/liyong888/p/7688390.html