我正在尝试通过套接字发送对象列表。
列表中的对象包含一个不可序列化的对象,因此无法发送,但它的基类是完全可序列化的,并包含我需要的所有字段。
所以我要做的是将列表转换为基类列表。我能想到的唯一方法就是如下:
// 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异常。从调试代码我可以看到新列表仍然是子类的列表,即使它已被强制转换。
有没有办法实现我想要做的事情?
答案 0 :(得分: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));
答案 1 :(得分:0)
您的方法不起作用,因为即使您可以使用超类变量来引用子类对象,该对象本身也属于子类类型。
最好的方法是序列化子类,或从子类中提取数据并将它们写入新创建的超类。只需要一个静态实用工具方法就可以将转换构建到子类中....
答案 2 :(得分:0)
Casting不会更改对象的类型。如果对象具有另一种类型,它允许获取对象的另一种类型的引用。向上传播绝不是必要的。你可以使用
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));
}
答案 3 :(得分:0)
你的问题体现了矛盾。如果基类是Serializable,那么它的所有派生类都是如此。如果派生类包含对不可序列化对象的引用,则只需使它们成为瞬态。