Instanceof возвращает false для того же класса после сериализации - PullRequest
0 голосов
/ 01 ноября 2018

Instanceof возвращает false для того же класса после org.springframework.security.oauth2.common.util.SerializationUtils fastxml десериализации в загрузочном приложении Spring

new ObjectMapper().readValue(serialized, User.class);

Класс

public class User implements Serializable {//...
}

Поскольку новый объект getClass (). GetClassloader () возвращает другой загрузчик классов, как исправить это и приведение проблемы?

1 Ответ

0 голосов
/ 01 ноября 2018

В этом случае вам следует сравнивать имена классов, а не использовать 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
}

UPDATE:

Если вам все еще нужно наложить объект, есть обходной путь:

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