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

このエラーは、シリアライズClientServiceThreadできない をシリアライズしようとしたために発生します。どういうわけか、そのうちの 1 つは の一部ですLot。がフィールド (または を含むフィールド)Lotで宣言されていない場合、そのようなフィールドを持つクラスの非静的内部クラスである可能性があります。その場合、外部クラスのインスタンスは の (非表示の) メンバーになります。ClientServiceThreadClientServiceThreadLotLot

解決策は、シリアル化可能にするか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 に答える