2013-03-17 196 views
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異常。從調試代碼我可以看到,新列表仍然是子類的列表,即使它已經被轉換。

有沒有辦法實現我想要做的?

回答

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 
} 

然後N:

baseClass.add(new BaseClass(subClass)); 
0

你的方法是行不通的,因爲即使你可以使用一個超類變量引用子類對象,對象本身是子類類型的。

最好的方法是序列化子類,或從子類中提取數據並將它們寫入新創建的超類。只需要一個靜態的實用工具方法來進行轉換構建到子類中...

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

你的問題體現了矛盾的條款。如果基類是可序列化的,那麼它的所有派生類。如果您的派生類包含對不可序列化對象的引用,只需讓它們爲瞬態即可。