getClass() 返回的 Class 对象与创建对象时的类加载器强绑定,不随动态类加载变化;不同加载器加载的同名类互不兼容,需显式通过目标类加载器获取 Class。

getClass() 返回的 Class 对象与当前类加载器强绑定,不反映动态类加载器的实际加载上下文。
getClass() 获取的是定义该实例的类加载器所加载的 Class
调用对象的 getClass() 方法,返回的是创建该对象时所用的类加载器加载的 Class 实例。即使后续通过其他类加载器(如自定义 ClassLoader)重新加载了同名类,原对象的 getClass() 结果也不会改变。这是因为 Class 对象在 JVM 中是类加载器的产物,每个类加载器对同一类名可产生独立的 Class 实例,而对象只关联其诞生时的那个 Class。
动态类加载场景下 getClass() 无法识别“新版本”类
当使用热部署、插件系统或 OSGi 等机制动态替换类时,新类由新类加载器加载,老对象仍持有旧 Class 的引用。此时:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- getClass() 返回旧 Class,不是新加载的同名类
- instanceof、Class.isAssignableFrom() 等基于 Class 的判断会失败,因为新旧 Class 属于不同加载器,彼此不兼容
- 反射调用方法时,若目标方法在新类中修改或新增,老对象的 getClass() 查不到这些变更
替代方案:显式获取期望类加载器中的 Class
若需与动态加载的类交互,应绕过对象本身的 getClass(),改用类加载器主动加载:
立即学习“Java免费学习笔记(深入)”;
- 通过 Thread.currentThread().getContextClassLoader().loadClass("com.example.Foo") 获取当前上下文类加载器加载的 Class
- 在插件或模块环境中,优先使用模块自己的 ClassLoader(如 Bundle.getClassLoader())来 loadClass
- 避免依赖对象.getClass() 做类型检查或反射入口;改为按业务语义明确指定类名和预期加载器
注意 equals 和 hashCode 在跨加载器 Class 间的失效
不同类加载器加载的相同全限定名类,其 Class 对象互不相等(getClass() != getClass()),hashCode 也不同。因此不能用 Class 引用作 Map 的 key 或 Set 的元素来统一管理多版本类——除非你确保所有操作都限定在同一类加载器范围内。

















