我想测试两个值是否具有相同的类:

x.getClass.equals(y.getClass)


但是,如果一个(或两个)值实际上属于CGLib Enhancer构造的类,则此比较应该成功。

显而易见的解决方案是在类名称中搜索$$EnhancerByCGLIB$$...,将其删除,然后比较类名称的其余部分(和类加载器)。有更好的选择吗?

最佳答案

cglib允许用户设置NamingStrategy,这使得替换EnhancerByCGLIB标签不可靠,因为可以随意命名一个类。

识别cglib类的最可靠方法是检查是否存在字段CGLIB$BOUND,该字段已硬编码到库中,因此名称不能更改。如果类中存在此类字段,则需要检查:


有实现的任何接口。如果存在至少一个接口,则增强的类可能是该接口。 (您可能会找到必须忽略的cglib的Factory接口。)
有一个不是java.lang.Object的超类。即使接口得到增强,显然也定义了一个超类。


因此,作为检测算法的近似值,您可以使用:

static Class<?> original(Class<?> type) {
  try {
    type.getDeclaredField("CGLIB$BOUND");
    if (type.getSuperclass() != Object.class) {
      return type.getSuperclass();
    }
    for (Class<?> iFace : type.getInterfaces()) {
      if (iFace != Factory.class) {
        return iFace;
      }
    }
    return Object.class;
  } catch (NoSuchFieldException ignored) {
    return type;
  }
}


请注意,cglib允许为类生成代理,这些类也实现了多个接口,上述展开将返回超类。

关于java - 比较类直至CGLib增强,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40487097/

10-10 06:06