簡體   English   中英

Java 序列化/反序列化給出 null object 參考

[英]Java Serialization/De-serialization giving null object references

我正在做一個小組項目,我們遇到了軟件序列化部分的問題。 我們有 class 協議:



    import java.io.Serializable;

    import javax.swing.table.TableModel;

    public class Protocol implements Serializable{


        private static final long serialVersionUID = 3474882407641871963L;
        private int state;//0 = logged out 
        //1=logged in waiting for search 
        //2= search query sent
        private String output;
        private TableModel searchResults;

        public Protocol(int state){
            this.output = "";
            this.state = 0;
            this.searchResults = null;
        }

        public void setState(int s) {
            this.state = s;
        }

        public void setOutput(String o) {
            this.output = o;
        }

        public void setSearchResults(TableModel results) {
            this.searchResults = results;
        }

        public String getOutput() {
            return this.output;
        }

        public int getState(){
            return this.state;
        }
        public TableModel getSearchResults(){
            return this.searchResults;
        }


    }

我們還有 SearchResult class:


    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;

    import javax.swing.event.TableModelListener;
    import javax.swing.table.TableModel;

    /**
     * An implementation of the TableModel interface that utilises a List of DataRow objects to
     * store the data.
     * 
     * @version 13/03/2014
     * @author Jake Darby
     * 
     * @see DataRow
     * @see TableModel
     */
    public class SearchResult implements TableModel 
    {
        private final List DATA;
        private static final int NUM_COLUMNS = 8;
        private final int NUM_ROWS;

        /**
         * Constructor that generates a SearchResult object from a set of Results of a query to the 'products' table
         * 
         * @param data The results of an SQL query of the 'products' table
         * @throws SQLException
         * 
         * @see ResultSet
         */
        public SearchResult (ResultSet data) throws SQLException
        {
            super();
            DATA = DataRow.generate(data);
            NUM_ROWS = DATA.size();
        }

        /**
         * Constructor creates an empty TableModel
         */
        public SearchResult()
        {
            super();
            DATA = new ArrayList();
            NUM_ROWS = 0;
        }

        @Override
        public int getRowCount() 
        {
            return NUM_ROWS;
        }

        @Override
        public int getColumnCount() 
        {
            return NUM_COLUMNS;
        }

        @Override
        public String getColumnName(int columnIndex) 
        {
            switch(columnIndex)
            {
            case 0:
                return "ID";
            case 1:
                return "Name";
            case 2:
                return "Price";
            case 3:
                return "Pack Quantity";
            case 4:
                return "Quantity in Stock";
            case 5:
                return "VAT";
            case 6:
                return "Order Date";
            case 7:
                return "Expiry Date";
            default:
                return null;
            }
        }

        @Override
        public Class getColumnClass(int columnIndex) 
        {
            switch(columnIndex)
            {
            case 0:
            case 3:
            case 4:
                return Integer.class;
            case 1:
            case 2:
            case 6:
            case 7:
                return String.class;
            case 5:
                return Boolean.class;
            default:
                return null;
            }
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) 
        {
            return false;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) 
        {
            DataRow row = DATA.get(rowIndex);
            switch(columnIndex)
            {
            case -1:
                return row.getPrice();
            case 0:
                return row.getID();
            case 1:
                return row.getName();
            case 2:
                return String.format("£%d.%02d", row.getPrice()/100, row.getPrice()%100);
            case 3:
                return row.getPackQuantity();
            case 4:
                return row.getQuantity();
            case 5:
                return row.getVAT();
            case 6:
                return row.getOrderDate() == null ? "N/A" : row.getOrderDate();
            case 7:
                return row.getExpiryDate() == null ? "N/A" : row.getExpiryDate();
            default:
                return null;
            }
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) 
        {/*No implementation*/}
        @Override
        public void addTableModelListener(TableModelListener l) 
        {/*No implementation*/}

        @Override
        public void removeTableModelListener(TableModelListener l) 
        {/*No implementation*/}

        @Override
        public String toString()
        {
            String result = "";
            for (int i = 0; i 

當我們通過客戶端-服務器套接字連接編寫協議 class 時,問題就出現了。 問題是協議 class 中的 TableModel object 在序列化/反序列化過程中的某個時刻變成了 null,我們還沒有做任何事情來解決這個問題。

到目前為止,我們已經嘗試過:

- 在 SearchResult 中實現 Serializable(我不認為這是必要的,因為 TableModel 實現了 Serializable)

- 將 TableModel 字段變量更改為協議中的 SearchResult 字段變量

非常感激任何的幫助。

此代碼正確地序列化和反序列化對象:

//write out the object
FileOutputStream fos = new FileOutputStream("out.myobj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Protocol p = new Protocol(4);
p.setState(5);
oos.writeObject(p);
oos.close();

//read it in
FileInputStream fis = new FileInputStream("out.myobj");
ObjectInputStream ois = new ObjectInputStream(fis);
Protocol x = (Protocol)ois.readObject();
ois.close();
System.out.println(x.getState());

輸出:

5

在這種情況下,與如何將對象寫入流有關。

僅供參考:TableModel是一個實現Serializable的接口。 在這里,僅對於協議,才需要實現Serializable。 如果您要寫出實現TableModel的類,那么該類也需要實現Serializable。

參見文檔:

http://docs.oracle.com/javase/7/docs/api/javax/swing/table/TableModel.html

(“協議控制器”)我認為你應該實現並使用它

import java.io.Serializable;
import javax.swing.table.TableModel;

@Named(value = "protocolController")
@SessionScoped
public class Protocol implements Serializable

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM