为了账号安全,请及时绑定邮箱和手机立即绑定

序列化后Instanceof为同一个类返回false

序列化后Instanceof为同一个类返回false

回首忆惘然 2021-12-22 16:00:21
在 org.springframework.security.oauth2.common.util.SerializationUtils 在 Spring 启动应用程序中进行 fastxml 反序列化后,Instanceof 为同一类返回 falsenew ObjectMapper().readValue(serialized, User.class);班级public class User implements Serializable {//...}因为新对象 getClass().getClassloader() 返回不同的类加载器,如何解决这个和转换问题?
查看完整描述

1 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

在这种情况下,您应该比较类名而不是使用instanceof. 即使类由不同的类加载器加载,规范名称也将相同:


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);

}


查看完整回答
反对 回复 2021-12-22
  • 1 回答
  • 0 关注
  • 337 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信