尝试编写对象时获取NotSerializableException
尝试序列化并将Lot
对象发送到套接字。 得到错误:
java.io.NotSerializableException: com.server.ClientServiceThread
为什么?
public class ClientServiceThread extends Thread {... // form here called sendObj ...} public class FlattenLot { public void sendObj(){ try { out = new ObjectOutputStream(oStream); out.writeObject(lot); // error out.flush(); out.close(); } catch (IOException ex) { ex.printStackTrace(); } }
批次类:
import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Date; import java.util.Calendar; public class Lot implements Serializable{ private static final long serialVersionUID = 1L; public ArrayList clientBidsLog = new ArrayList(); public ArrayList bidLog = new ArrayList(); private List bids = new ArrayList(); private List clients = new ArrayList(); private String NAME; private int INITIAL_PRICE; private int MAX_BID = 0; public volatile boolean notAvailable = false; Lot(String name, int initPrice){ NAME = name; INITIAL_PRICE = initPrice; } public synchronized String getName(){return NAME;} public synchronized int getInitPrice(){return INITIAL_PRICE;} public synchronized void subscribe(ClientServiceThread t){ clients.add(t); } public synchronized void unsubscribe(ClientServiceThread t){ clients.remove(t); } public synchronized boolean makeBid(ClientServiceThread t,int i){ if(i > INITIAL_PRICE && i > MAX_BID){ clientBidsLog.add(t); bidLog.add(i); bids.add(i); MAX_BID = i; t.LAST_BID = i; notifyAllSubscribers("New bid: "+this.getMaxBid()+" made by "+this.clientBidsLog.get(this.clientBidsLog.size()-1).CLIENT_NAME); return true; }else{ return false; } } public synchronized void notifyAllSubscribers(String msg){ for (ClientServiceThread client : clients){ client.lotUpdated(this, msg); } } public synchronized int getMaxBid(){return MAX_BID;} private Date time; public Lot() { time = Calendar.getInstance().getTime(); } public Date getTime() { return time; } }
Lot
包含
public ArrayList clientBidsLog private List clients
如果您希望序列化此字段,请标记ClientServiceThread
serializable
如果您不希望它被序列化,只需将其标记为transient
public transient ArrayList clientBidsLog private transient List clients
尝试序列化不可序列化的ClientServiceThread
会导致该错误。 不知何故,其中一个是Lot
一部分。 如果未使用ClientServiceThread
字段(或使用包含ClientServiceThread
的字段)声明Lot
,则另一种可能性是Lot
是具有此类字段的类的非静态内部类。 外部类实例将是Lot
的(隐藏)成员。
解决方案是使ClientServiceThread
序列化(不太可能来自其名称),或者通过将相关字段标记为transient
(或从Lot
类中删除它们)将其从序列化中消除。
有几个答案表明您可以将ClientServiceThread
序列化为可能的解决方案。
警告 – 这可能不起作用!
是的,您可以声明一个实现Serializable
的Thread
子类,但Java序列化机制无法序列化实时线程的堆栈。 实际上,我甚至认为它不会成功地序列化非活动线程的状态(例如线程的ThreadGroup
引用),所以你可能会得到更多的exception。
我认为你唯一的选择是通过声明这些集合是transient
来从序列化中排除线程。