2

尝试序列化并将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;
    }
    }
4

3 回答 3

5

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

解决方案是要么使ClientServiceThread序列化(不太可能,从它的名称),要么通过标记相关字段(或从类transient中删除它们)从序列化中消除它。Lot

于 2012-06-06T03:41:09.440 回答
4

Lot包含

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

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

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

public transient ArrayList<ClientServiceThread> clientBidsLog 
private transient List<ClientServiceThread> clients
于 2012-06-06T03:41:30.560 回答
2

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

警告 - 这可能行不通!

是的,你可以声明一个Thread实现的子类Serializable,但是Java序列化机制不能序列化一个活动线程的堆栈。事实上,我什至认为它不会成功序列化非活动线程的状态(例如线程的ThreadGroup引用),因此您可能会遇到更多异常。

我认为您唯一的选择是通过将这些集合声明为transient.

于 2012-06-06T04:03:22.660 回答