2

我正在尝试通过套接字发送对象列表。

列表中的对象包含一个不可序列化的对象,因此无法发送,但是它的基类是完全可序列化的并包含我需要的所有字段。

所以我想做的是将列表转换为基类的列表。我认为这样做的唯一方法如下:

// subClassList is an ArrayList<SubClass>
ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>();
for(SubClass subClass: subClassList) {
    // cast to the base class
    baseClassList.add((BaseClass)subClass);
}

然而,这不起作用,因为我仍然得到相同的 NotSerializableException 异常。通过调试代码我可以看到新列表仍然是子类的列表,即使它已经被强制转换。

有没有办法实现我想要做的事情?

4

4 回答 4

1

转换引用不会改变实际对象的类型:

String foo = "hello";
Object bar = (Object) foo;
System.out.println(bar); // Hello
System.out.println(bar.getClass()); // java.lang.String

如果你只想一个基类的实例,你可以在基类中创建一个构造函数,它只是在给定一个基类的实例的情况下创建一个新的基类实例,而不尝试执行任何类型的深拷贝:

public BaseClass(BaseClass other) {
    this.x = other.x;
    this.y = other.y;
    this.z = other.z;
    // etc
}

然后在您显示的代码中:

baseClass.add(new BaseClass(subClass));
于 2013-03-17T14:14:45.450 回答
0

您的方法不起作用,因为即使您可以使用超类变量来引用子类对象,对象本身也是子类类型。

最好的方法是序列化子类,或者从子类中提取数据并将它们写入新创建的超类。只需有一个静态实用程序方法即可将转换构建到子类中......

于 2013-03-17T14:16:44.403 回答
0

强制转换不会改变对象的类型。如果对象具有这种其他类型,它允许获取该对象的另一种类型的引用。向上转型从来都不是必需的。您可以使用

String s = "hello";
Object o = s; // no cast needed

向下转换是必要的,并且仅当对象具有您将其转换为的类型时才会起作用:

Object o = "hello";
Object o2 = Integer.valueOf(5);
String s = (String) o; // OK because o is a String
String s2 = (String) o2; // ClassCastException, because o2 is not a String.

所以,你的代码相当于

ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>();
for(SubClass subClass: subClassList) {
    // cast to the base class
    baseClassList.add(subClass);
}

您必须使用复制构造函数创建新类型的新对象:

ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>();
for(SubClass subClass: subClassList) {
    // cast to the base class
    baseClassList.add(new BaseClass(subClass));
}
于 2013-03-17T14:17:03.733 回答
0

你的问题体现了一个矛盾的术语。如果基类是可序列化的,那么它的所有派生类也是。如果您的派生类包含对不可序列化对象的引用,只需将它们设为瞬态即可。

于 2013-03-18T00:12:49.990 回答