Instanceof returns false for same class 序列化后
Instanceof returns false for same class after serialization
Instanceof returns false for same class after org.springframework.security.oauth2.common.util.SerializationUtils fasterxml deserialization in Spring boot application
new ObjectMapper().readValue(serialized, User.class);
Class
public class User implements Serializable {//...
}
因为新对象 getClass().getClassloader() returns 不同的 classloader,如何解决这个问题和 casting 问题?
在这种情况下,您应该比较 class 个名称,而不是使用 instanceof
。即使 classes 由不同的 class 加载程序加载,规范名称也将相同:
public boolean haveSameCanonicalName(Object object, Class<?> clazz) {
String actualClassName = object.getClass().getCanonicalName();
String expectedClassName = clazz.getCanonicalName();
return actualClassName.equals(expectedClassName);
}
然后你可以这样使用它:
if (haveSameCanonicalName(user, User.class)) {
// Do something here
}
更新:
如果您仍然需要转换对象,有一个解决方法:
public class CrossCastUtils {
private final ObjectOutputStream oos;
private final ObjectInputStream ois;
public CrossCastUtils() throws IOException {
final PipedOutputStream pos = new PipedOutputStream();
final PipedInputStream pis = new PipedInputStream(pos);
oos = new ObjectOutputStream(pos);
ois = new ObjectInputStream(pis);
}
public <T> T cast(Object object) throws IOException, ClassNotFoundException {
oos.writeObject(object);
oos.flush();
return (T) ois.readObject();
}
尝试运行这个测试:
@Test
public void testCrossCast(){
Object initial = ... // retrieve it as you did before
User result = CrossCastUtils.cast(initial);
assertFalse(initial instanceof User);
assertTrue(result instanceof User);
}
Instanceof returns false for same class after org.springframework.security.oauth2.common.util.SerializationUtils fasterxml deserialization in Spring boot application
new ObjectMapper().readValue(serialized, User.class);
Class
public class User implements Serializable {//...
}
因为新对象 getClass().getClassloader() returns 不同的 classloader,如何解决这个问题和 casting 问题?
在这种情况下,您应该比较 class 个名称,而不是使用 instanceof
。即使 classes 由不同的 class 加载程序加载,规范名称也将相同:
public boolean haveSameCanonicalName(Object object, Class<?> clazz) {
String actualClassName = object.getClass().getCanonicalName();
String expectedClassName = clazz.getCanonicalName();
return actualClassName.equals(expectedClassName);
}
然后你可以这样使用它:
if (haveSameCanonicalName(user, User.class)) {
// Do something here
}
更新:
如果您仍然需要转换对象,有一个解决方法:
public class CrossCastUtils {
private final ObjectOutputStream oos;
private final ObjectInputStream ois;
public CrossCastUtils() throws IOException {
final PipedOutputStream pos = new PipedOutputStream();
final PipedInputStream pis = new PipedInputStream(pos);
oos = new ObjectOutputStream(pos);
ois = new ObjectInputStream(pis);
}
public <T> T cast(Object object) throws IOException, ClassNotFoundException {
oos.writeObject(object);
oos.flush();
return (T) ois.readObject();
}
尝试运行这个测试:
@Test
public void testCrossCast(){
Object initial = ... // retrieve it as you did before
User result = CrossCastUtils.cast(initial);
assertFalse(initial instanceof User);
assertTrue(result instanceof User);
}