【发布时间】:2015-09-24 20:43:13
【问题描述】:
我有一个带有以下代码的Trade 对象,它实现了Serializable 接口,但由于它包含javafx 属性,我得到了这个java.io.NotSerializableException,因此未能正确执行writeObject() 和readObject()。我的最终目标是能够使用ObjectOutputStream 和ObjectInputStream
我阅读了 3 个链接:
NotSerializableException on SimpleListProperty
由于我的Trade 类正在运行ScheduledService 以从Google Finance 获取收盘价,我知道我需要在readObject() 内调用startService() 以确保当readObject() 方法是调用并且对象被反序列化,线程将再次重新启动。
此外,我知道我需要在我的Trade 类中定义这两个私有方法。
private void writeObject(ObjectOutputStream out) throws IOException
{
out.defaultWriteObject();
// What else should I write in here?
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
// our "pseudo-constructor"
in.defaultReadObject();
// Not sure what else I need to write in here
// now we are a "live" object again, so let's run rebuild and start
startService();
}
问题:我已经阅读了上面的第三个链接,但我仍然对上面这两个私有方法还有什么感到困惑?
因为我的交易对象有很多属性,但它真正需要的只是
只是buySell,transactionDate,symbol, double volume, double price 来构造一个对象。那么我应该将其余属性设置为transient 吗?
public class Trade implements Serializable{
// properties
private Long creationTime;
private int counter;
private ObjectProperty<LocalDate> transactionDate;
private StringProperty symbol;
private StringProperty details;
private StringProperty buySell;
private DoubleProperty volume;
private DoubleProperty price;
private ReadOnlyDoubleWrapper transactionFee;
private final ReadOnlyDoubleWrapper closingPrice;
private final PauseTransition delay;
private ReadOnlyBooleanWrapper caution;
private final ScheduledService<webScraping> stockService = new ScheduledService<webScraping>() {
// web scrape google finance data
...
}
// constructor
public Trade(BuySell buySell, LocalDate transactionDate, String symbol, double volume, double price){
...
startService();
creationTime = Calendar.getInstance().getTimeInMillis();
}
// getters and setters and instance methods that return the properties themselves
public Long getCreationTime(){
return this.creationTime;
}
private Object writeReplace() {
return new TradeProxy(this);
}
private void readObject(ObjectInputStream stream)
throws InvalidObjectException {
throw new InvalidObjectException("Proxy required");
}
...
private static class TradeProxy implements Serializable{
private String buySell;
private LocalDate transactionDate;
private String stockTicker;
private double price;
private double volume;
private Long creationTime;
private TradeProxy(Trade trade){
this.buySell = trade.getBuySell();
this.transactionDate = trade.getTransactionDate();
this.stockTicker = trade.getStockTicker();
this.price = trade.getPrice();
this.volume = trade.getVolume();
this.creationTime = trade.getCreationTime();
}
private void writeObject(ObjectOutputStream s ) throws IOException{
s.defaultWriteObject();
}
private Object readResolve() throws ObjectStreamException{
return new Trade(this.buySell,this.transactionDate, this.symbol, this.volume, this.price);
}
}
}
更新:我已经更新了我的代码。但是由于creationTime 不是Trade 构造函数的参数,所以我不知道如何序列化/反序列化它。更准确地说,如果我在某个时间创建一个Trade 对象说creationTime = 1443444301488,我希望这个对象被序列化,当我读入对象并反序列化它时,我希望creationTime 完全相同原来如此(即 1443444301488) 我不知道如何实现这一点。这是我现在面临的问题。
【问题讨论】:
-
要么对序列化中不需要的东西使用瞬态,要么将类分成两个类,一个简单的类,它只包含交易信息(符号、价格等),应该是可序列化的,并且可能也会导致更简洁的设计。
-
您能否提供一些代码示例,说明在这种情况下应该在
readObject()和writeObject()方法中使用什么?你能否也给我一个例子,在我的情况下,你将如何将班级分成 2 个班级?谢谢 -
我不知道您指的是哪种情况,但在任何一种情况下,您可能甚至都不需要 writeObject 和 readObject 方法。默认会序列化所有非瞬态字段,我认为这是你想要的。