当前位置: 首页 > 知识库问答 >
问题:

将类型a的类反序列化为具有相同SerialVersionId、字段和方法的类型B

唐沈义
2023-03-14

给我java。lang.ClassCastException:slz。不能向slz施放A。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实现了serializable,它们具有相同的字段和方法以及相同的串行版本id

共有3个答案

卫志泽
2023-03-14
public class A extends B {}

将你的类A更改为上面的代码,这应该会起作用。发生类强制转换异常是因为类A和B的类型不同。反序列化过程返回类型为A的对象,您试图将其强制转换为B,这就是它失败的原因。

漆雕伟志
2023-03-14

不能将A反序列化为B,因为它们是不同的类。他们实际上是一样的并不重要,他们仍然是不同的阶级。这就像试图将一只狗反序列化为一只猫,它们有相同数量的腿等,但它们是不同的动物。

束雅达
2023-03-14

毕竟他们是不同的阶级。在序列化过程中,进程需要跟踪其类型,因为在反序列化过程中,运行时需要知道实例化哪种类型。当类型不匹配时,将出现类强制转换异常。

但是,您应该研究readResolve()方法,该方法将在反序列化期间调用,您可以使用它从流中创建不同的类型。如果将以下方法添加到类A中,反序列化将起作用:

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

从Serializable接口中的Javadocs:

 * <p>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:
 *
 * <PRE>
 * ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
 * </PRE><p>
 *
 * This writeReplace method is invoked by serialization if the method
 * exists and it would be accessible from a method defined within the
 * class of the object being serialized. Thus, the method can have private,
 * protected and package-private access. Subclass access to this method
 * follows java accessibility rules. <p>
 *
 * Classes that need to designate a replacement when an instance of it
 * is read from the stream should implement this special method with the
 * exact signature.
 *
 * <PRE>
 * ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
 * </PRE><p>
 *
 * This readResolve method follows the same invocation rules and
 * accessibility rules as writeReplace.<p>
 类似资料:
  • 问题内容: 以下代码可以正常工作。在两个不同的结构上操作并打印该结构的字段的两种方法: 在控制台中显示所需的输出: 现在 ,如果我以以下方式更改方法签名,则会出现编译错误。我只是将方法的接收者移动到方法的参数: 我什至无法编译程序: 问 :为什么 当 方法具有相同的名称和Arity 时 ,我可以在接收器中互换结构类型,而不能在参数中互换结构类型? 问题答案: 因为Go不支持在其参数类型上重载用户定

  • 我有一门课是这样的: 但是当我试图序列化它时,我收到一个错误,上面写着“试图序列化java.lang.class:java.lang.字符串。忘记注册一个类型适配器了吗?”。所以我创建了这个适配器: } 并登记如下: 但我还是犯了同样的错误<我做错了什么 适配器的实现看起来正常吗?

  • 问题内容: 假设我们有这样的结构: JSON: 和对应的POJO: 响应类 身体类 CatWrapper.class 类别 但是现在让我们说,我们具有相同的结构,但是我们得到的不是 我在上使用GSON(默认json解析器),在提供解决方案时请考虑一下。 我们可以在此处使用泛型,因此响应如下所示: 但是我们不能,因为字段名称是特定于类的。 题: 我如何做才能自动序列化它而不创建太多样板类?我并不真的

  • 我有一个JSONNode对象,它可以包含任何JSON内容。示例: 我想将这个字符串中的每个JSON字段反序列化为不同类型的Java对象,如下所示: 假设我知道每个字段应反序列化为的类类型。什么是最好和最优化的方式去做这件事? 编辑:进一步澄清我的要求: 我想到的方法是为TypeA、TypeB、TypeC等创建对象,并用相关的JsonPropery注释对它们进行注释。我不清楚的是,如何单独反序列化每

  • 问题内容: 我想反序列化JSON(使用Jackson 1.9.11和RestTemplate 1.0.1),其中一个字段可能具有更多类型含义,例如: 要么 一个或另一种情况对于一个特定类型的设置器(String od custom Response类)都可以正常工作,但是当我将实体bean重写的设置器放入能够处理这两种情况时,将引发异常: 我当时在考虑三种解决方案,但没有任何一种可行: 仅使用St

  • 我试图反序列化2种不同类型的列表,包括它们的派生类 为了更好地解释它,我做了下面的例子 我有2个系统: API系统 与下列实体合作: 应用系统 使用以下DTO 使用此示例,API系统返回一个