public class TestDemo {
//测试
@Test
public void fun01() {
TestDemo q=new TestDemo();
A a = new A();
q.adapter(a);
} private void adapter(Base base){ HashMap<Class<? extends Base>,String> class2methodName=new HashMap<Class<? extends Base>,String>()
{
private static final long serialVersionUID = 1L;
{
put(A.class,"printA");
put(B.class,"printB");
}
};
System.out.println(class2methodName.get(base.getClass()));
invokeMethod(this,class2methodName.get(base.getClass()),new Class<?>[]{Base.class},new Object[]{base});
} public void printA(Base base) {
A a=(A)base;
System.out.println("is A:"+a.num);
}
public void printB(Base base) {
B b=(B)base;
System.out.println("is B:"+b.num);
} @SuppressWarnings("unchecked")
private static <T> T invokeMethod(T obj, String methodName, Class<?>[] classes, Object[] objects) {
T val = null;
try {
Method m = null;
if(objects != null && classes != null){
m = obj.getClass().getDeclaredMethod(methodName, classes);
val = (T)m.invoke(obj, objects);
}else{
m = obj.getClass().getDeclaredMethod(methodName);
val = (T)m.invoke(obj);
}
} catch (Exception e) {
e.printStackTrace();
}
return val;
} private class Base{
public int num = 1;
} private class A extends Base{
public int num = 2;
} private class B extends Base{
public int num = 3;
}
}

见知乎 : 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对象..

  

 

知乎上看到的关于类.class,对象.getClass的更多相关文章

  1. 你好,C++(38)从问题描述中发现对象的属性和行为 6.4 工资程序成长记:类与对象(上)

    6.4  工资程序成长记:类与对象 “夜半三更哟,盼天明:寒冬腊月哟,盼春风.若要盼得哟,涨工资,岭上……”自从上次老板许诺给小陈涨工资以后,一转眼又过去几个月了,可是涨工资的事一点动静都没有.小陈只 ...

  2. Java知多少(7)类与对象

    Java是一门面向对象的编程语言,理解Java,首先要理解类与对象这两个概念. Java中的类可以看做C语言中结构体的升级版.结构体是一种构造数据类型,可以包含不同的成员(变量),每个成员的数据类型可 ...

  3. Java知多少(99)Graphics2D类的绘图方法

    Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管理以及文字布局等更精确的 ...

  4. Android-通知栏上的RemoteView

    Android-通知栏上的RemoteView 学习自 <Android开发艺术探索> https://developer.android.google.cn/reference/andr ...

  5. 在知乎上看到 Web Socket这篇文章讲得确实挺好,从头看到尾都非常形象生动,一口气看完,没有半点模糊,非常不错

    在知乎上看到这篇文章讲得确实挺好,从头看到尾都非常形象生动,一口气看完,没有半点模糊,非常不错,所以推荐给大家,非常值得一读. 作者:Ovear链接:https://www.zhihu.com/que ...

  6. FTP上传-封装工具类

    import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...

  7. 实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法

    实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法 #import <Found ...

  8. Google 内部代码是不支持异常(Excepton)的,C++ 异常的优劣之处有许多讨论(知乎上的讨论)

    最近 Google 开源了其内部多年使用的 C++ 代码库 Abseil 作为 C++ 标准库的补充,并会对其进行持续更新,本文对其进行简要介绍. 一句话概括,这个库的特点是用 C++ 11 的代码实 ...

  9. ftp上传下载工具类

    package com.taotao.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNo ...

随机推荐

  1. BMC手册 — 第一模块 BMC介绍

    BMC的监控 其实是BPPM与 Patrol 产品的结合.早期它们二个是单独监控产品,后来BPPM被BMC收购.拿来与patrol产口集成产品整合后,BPPM主要用来做展示与告警处理,底层采集采用pa ...

  2. python 素因子分解

    在使用python解决问题之前,我们先说一下,什么是素因子分解 所谓素因子分解就是,先找这个数的所有约数(约数即:a%b == 0,也就是a可以被b整除) 例如:20的约数集合为 [1, 2, 5, ...

  3. 【Web性能进阶】1.无线网络基础

    一.无所不在的连接 针对不通的使用场景,无线网络技术有很多种. 鉴于无线网络技术如此多样,笼统地概括所有无线网络的性能优化手段是不可能的.好在大多数无线技术的原理都是相通的,衡量性能的指标和约束条件也 ...

  4. IDEA热部署(三)---jetty插件调试(转)

    我们在开发的时候习惯对于项目的框架进行分层,在idea中对于不同的层,我们使用module来进行划分,不同的module之间是通过maven来进行依赖的. 我们的项目结构是这样的,admin是我们的w ...

  5. spring boot部署系统--morphling简介

    Morphling 简介 Morphling是一套基于Spring Boot 1.5开发的部署系统,依赖简单,一套Mysql即可运行,操作简单明了,适用于百台规模几下机器的运维操作 功能概述 系统部署 ...

  6. linux下用split命令将一个大的文件拆分成若干小文件

    命令 split -l 50 wlan_date.txt wlan 说明:按50行给文件进行拆分,如果没有最后面的参数,命名将会是xaa,xab等.

  7. 【java设计模式】【行为模式Behavioral Pattern】迭代器模式Iterator Pattern

    package com.tn.pattern; public class Client { public static void main(String[] args) { Object[] objs ...

  8. Layui常见问题

    为什么表单不显示?当你使用表单时,Layui会对select.checkbox.radio等原始元素隐藏,从而进行美化修饰处理.但这需要依赖于form组件,所以你必须加载 form,并且执行一个实例. ...

  9. less基础语法

    变量 //->LESS代码 @link-color: #428bca; @link-color-hover: darken(@link-color, 10%); a { color: @link ...

  10. java获取当前应用的运行信息(内存,线程,运行时间,状态等)

    一:目的 写这一段程序的原因是需要监控部署的的应用是否正常运行,并且显示其运行状态.在进程莫名死掉后甚至可以自动启动该应用. 首先这段代码可以获取的信息如下 /** * 当前进程运行的主机名 */ p ...