尝试编写对象时获取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序列化为可能的解决方案。

警告 – 这可能不起作用!

是的,您可以声明一个实现SerializableThread子类,但Java序列化机制无法序列化实时线程的堆栈。 实际上,我甚至认为它不会成功地序列化非活动线程的状态(例如线程的ThreadGroup引用),所以你可能会得到更多的exception。

我认为你唯一的选择是通过声明这些集合是transient来从序列化中排除线程。