Десериализация класса типа A для типа B, который имеет тот же serialVersionUID, поля, методы - PullRequest
1 голос
/ 06 июня 2019

Дает мне java.lang.ClassCastException: slz.A не может быть приведен к slz.B Почему?Оба класса имеют одинаковые поля и метод.Почему я не могу преобразовать сериализованный объект типа A в тип B при десериализации?

public class A implements Serializable {

  private  String var1;
  private String var2;
  private static final long serialVersionUID = 4L;

  public String getVar1() {
    return var1;
  }

  public void setVar1(String var1) {
    this.var1 = var1;
  }

  public String getVar2() {
    return var2;
  }

  public void setVar2(String var2) {
    this.var2 = var2;
  }
}


public class B implements Serializable {

  private  String var1;
  private String var2;
  private static final long serialVersionUID = 4L;

  public String getVar1() {
    return var1;
  }

  public void setVar1(String var1) {
    this.var1 = var1;
  }

  public String getVar2() {
    return var2;
  }

  public void setVar2(String var2) {
    this.var2 = var2;
  }

  @Override
  public String toString() {
    return var1 + " " + var2;
  }
}

public class Test {

  public static void main(String[] args)  {
    A a = new A();
    a.setVar1("d");
    a.setVar2("e");

    B b = null;

    try(FileOutputStream fileOut = new FileOutputStream("Test.ser");
        ObjectOutputStream outputStream = new ObjectOutputStream(fileOut);
        FileInputStream inputStream = new FileInputStream("Test.ser");
        ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);){
      outputStream.writeObject(a);
      b = (B) objectInputStream.readObject();

    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }
}

Два класса A и B реализуют сериализуемые, они имеют одинаковые поля и методы и одинаковый идентификатор последовательной версии

Ответы [ 3 ]

3 голосов
/ 06 июня 2019

В конце концов, это разные классы. Во время сериализации процесс должен будет отслеживать его тип, потому что во время десериализации среде выполнения необходимо знать, какой тип создать. Когда типы не совпадают, вы получите исключение приведения класса.

Однако вы должны изучить метод readResolve(), который будет вызываться во время десериализации и который вы можете использовать для создания другого типа из потока. Если бы вы добавили следующий метод в ваш класс A, десериализация сработала бы:

public Object readResolve() throws ObjectStreamException{
  return new B();
}

Из Javadocs в интерфейсе Serializable:

 * Serializable classes that need to designate an alternative object to be
 * used when writing an object to the stream should implement this
 * special method with the exact signature:
 *
 * 
 * ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
 * 

* * Этот метод writeReplace вызывается сериализацией, если метод * существует и будет доступен из метода, определенного в * класс сериализуемого объекта. Таким образом, метод может быть закрытым, * защищенный и пакетно-приватный доступ. Подкласс доступа к этому методу * следует правилам доступности Java.

* * Классы, которые должны назначить замену, когда экземпляр этого * читается из потока должен реализовать этот специальный метод с * точная подпись. * *

 * ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
 * 

* * Этот метод readResolve следует тем же правилам вызова и * правила доступности как writeReplace.

2 голосов
/ 06 июня 2019

Вы не можете десериализовать A в B, потому что это разные классы.Неважно, что они фактически одинаковы, они все еще разные классы.Это все равно что пытаться десериализовать собаку в кошку, у нее одинаковое количество ног и т. Д., Но это разные животные.

0 голосов
/ 06 июня 2019
public class A extends B {}

Измените свой класс A на код выше, и это должно работать.Исключение приведения класса происходит потому, что оба ваших класса A и B не одного типа.В процессе десериализации возвращается объект типа A, и вы пытаетесь привести его к B, и поэтому он не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...