尝试编写对象时获取NotSerializableException

时间:2012-06-06 03:33:19

标签: java serialization

尝试序列化并将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<ClientServiceThread> clientBidsLog = new ArrayList<ClientServiceThread>();
    public ArrayList<Integer> bidLog = new ArrayList<Integer>();

    private List<Integer> bids = new ArrayList<Integer>();
    private List<ClientServiceThread> clients = new ArrayList<ClientServiceThread>();

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

3 个答案:

答案 0 :(得分:5)

错误是由尝试序列化ClientServiceThread引起的,Lot不可序列化。不知何故,其中一个是Lot的一部分。如果未使用ClientServiceThread字段(或包含ClientServiceThread的字段)声明Lot,则另一种可能性是Lot是非静态内部类一个确实有这样一个领域的类。然后外部类实例将成为ClientServiceThread的(隐藏)成员。

解决方案是使transient可序列化(不太可能来自其名称),或者通过标记相关字段Lot(或从{{1}}中删除它们来将其从序列化中消除) {1}}类)。

答案 1 :(得分:4)

Lot包含

public ArrayList<ClientServiceThread> clientBidsLog 
private List<ClientServiceThread> clients

如果您希望序列化此字段,请标记ClientServiceThread serializable

如果您不希望序列化,只需将其标记为transient

public transient ArrayList<ClientServiceThread> clientBidsLog 
private transient List<ClientServiceThread> clients

答案 2 :(得分:2)

有几个答案表明您可以将ClientServiceThread序列化声明为可能的解决方案。

警告 - 这可能不起作用!

是的,您可以声明实现Thread的{​​{1}}子类,但Java序列化机制无法序列化活动线程的堆栈。事实上,我甚至认为它不会成功地序列化非活动线程的状态(例如线程的Serializable引用),所以你可能会得到更多例外。

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