问题:
通过debug发现result.removeAll的时候 删不了
public boolean equals(Object obj) {
return obj instanceof OspSpringBoot2Initializer.OspBean && this.bean.equals(((OspSpringBoot2Initializer.OspBean)obj).bean);
}
this.bean.equals(((OspSpringBoot2Initializer.OspBean)obj).bean 这里返回了false
明明地址一致,那为什么返回了false?
定位问题:
进一步定位。
通过debug定位到: 最终调用java.lang.Object#equals方法的时候,this和obj的引用不一致所以返回false
通过栈帧可以看到:
调用了cglib增强类的equals方法
通过arthas jad 命令反编译出cglib类的代码
public final boolean equals(Object object) {
boolean[] arrbl = SalesNormalPoolService$$EnhancerByCGLIB$$e87bde91.$jacocoInit();
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor != null) {
arrbl[3] = true;
} else {
SalesNormalPoolService$$EnhancerByCGLIB$$e87bde91.CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
arrbl[4] = true;
}
if (methodInterceptor != null) {
boolean bl;
Object object2 = methodInterceptor.intercept((Object)this, CGLIB$equals$0$Method, new Object[]{object}, CGLIB$equals$0$Proxy);
if (object2 == null) {
bl = false;
arrbl[5] = true;
} else {
bl = (Boolean)object2;
arrbl[6] = true;
}
arrbl[7] = true;
return bl;
}
arrbl[8] = true;
return super.equals(object);
}
这里结果依赖于methodInterceptor.intercept((Object)this, CGLIB$equals$0$Method, new Object[]{object}, CGLIB$equals$0$Proxy);
我们继续看下intercept 这个方法
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//.. 省略 不会走这里的
}
发现是通过反射调用java.lang.Object#equals方法,此时是this.equals(args[0]) 发现地址不一致 结果返回false。
所以bug就定位到
method.invoke(this, args);
解决:
正确写法应该是:
methodProxy.invokeSuper(o, args);
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if (method.getDeclaringClass() == Object.class) {
return methodProxy.invokeSuper(o, args);
}
//.. 省略 不会走这里的
}
修改过后
在调用java.lang.Object#equals时
传入了o 和 args[0] ,它们两个地址相同,所以返回true
我们继续看下栈帧:
现在有调用CGLIB$equals$0:-1, SalesNormalPoolService$$EnhancerByCGLIB$$e87bde91
final boolean CGLIB$equals$0(Object object) {
boolean[] arrbl = SalesNormalPoolService$$EnhancerByCGLIB$$e87bde91.$jacocoInit();
arrbl[2] = true;
return super.equals(object);
}
也就是 现在的调用是:o == args[0] → true
以前的调用是:this == args[0] → false
标签:Object,false,CGLIB,arrbl,args,equals,cglib,true From: https://www.cnblogs.com/eiffelzero/p/18248330