【问题标题】:NotSerializableException, unpredictable?NotSerializableException,不可预测?
【发布时间】:2012-07-10 07:34:03
【问题描述】:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.lang.reflect.Constructor
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at javax.swing.event.EventListenerList.readObject(EventListenerList.java:272)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:991)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:498)
    at javax.swing.JComponent.readObject(JComponent.java:5478)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:991)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1685)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1341)
    at java.io.ObjectInputStream.access$300(ObjectInputStream.java:205)
    at java.io.ObjectInputStream$GetFieldImpl.readFields(ObjectInputStream.java:2126)
    at java.io.ObjectInputStream.readFields(ObjectInputStream.java:537)
    at java.awt.Container.readObject(Container.java:3712)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:991)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at javax.swing.event.EventListenerList.readObject(EventListenerList.java:272)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:991)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at projectserver.SQLHandler.listener(SQLHandler.java:156)
    at projectserver.SQLHandler.<init>(SQLHandler.java:27)
    at projectserver.Client.run(Client.java:82)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.NotSerializableException: java.lang.reflect.Constructor
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at javax.swing.event.EventListenerList.writeObject(EventListenerList.java:257)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
    at javax.swing.JComponent.writeObject(JComponent.java:5525)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1362)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1170)
    at java.io.ObjectOutputStream.access$300(ObjectOutputStream.java:161)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(ObjectOutputStream.java:1687)
    at java.io.ObjectOutputStream.writeFields(ObjectOutputStream.java:478)
    at java.awt.Container.writeObject(Container.java:3681)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at javax.swing.event.EventListenerList.writeObject(EventListenerList.java:257)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at projectclient.ConnectionPane.sendToServer(ConnectionPane.java:131)
    at projectclient.AddRecordFrame.btnAddRecordActionPerformed(AddRecordFrame.java:144)
    at projectclient.AddRecordFrame.access$000(AddRecordFrame.java:20)
    at projectclient.AddRecordFrame$2.actionPerformed(AddRecordFrame.java:94)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6504)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6269)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4860)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4686)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2713)
    at java.awt.Component.dispatchEvent(Component.java:4686)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:680)
    at java.awt.EventQueue$4.run(EventQueue.java:678)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

我不确定您需要什么代码,所以请发表评论,我会发布。我不能一直重现这个问题,但有时它会在重新启动后消失,有时它不会。我真的不知道是什么原因造成的。 AbstractTableModel 中是否有不可序列化的内容?我检查了我的表中没有空值,SQLTableModel 类中没有静态成员:

package projectcommon;

import java.io.Serializable;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;

/**
 * This class is used by both the server and client, and it defines how the data
 * from the database is organised and stored. Because it is serializable it
 * provides an easy means of communicating data with the server.
 *
 * @author Logan Dam
 */
public class SQLTableModel extends AbstractTableModel implements Serializable {

    /**
     * The variable used to store the table's column names.
     */
    String[] colNames;
    /**
     * The variable used to store the table's data.
     */
    ArrayList<Object[]> data;
    /**
     * An array defining the datatypes for the columns in the table.
     */
    Class<?>[] types;
    /**
     * A variable defining whether the user using the table is an admin or not.
     */
    private boolean isAdmin;
    /**
     * An array defining which columns in the table are editable.
     */
    private boolean[] isEditable;
    /**
     * A boolean variable that dictates whether the table is editable or not.
     * This is only used in special cases, such as when adding a new record to
     * the database.
     */
    private boolean addFrame = false;

    /**
     * Initialises a new {@code SQLTableModel} object based on predetermined data.
     *
     * @param colNames A {@code String} array containing the table's column names
     * @param types A {@code Class} array containing the table's data types.
     * @param data An {@code ArrayList} object containing the table's data.
     * @param isAdmin A {@code boolean} dictating whether the user is an admin or not.
     * @param isEditable A {@code boolean} array that defines which columns are editable
     * in the table.
     */
    public SQLTableModel(String colNames[], Class<?>[] types, ArrayList<Object[]> data, boolean isAdmin, boolean[] isEditable) {
    this.colNames = colNames;
    this.types = types;
    this.data = data;
    this.isAdmin = isAdmin;
    this.isEditable = isEditable;

    }

    /**
     * Get the data type of the given column.
     * @param columnIndex the index of the column.
     * @return A {@code Class} object representing the given column's type.
     */
    @Override
    public Class<?> getColumnClass(int columnIndex) {
//  System.out.println("columnindex " + columnIndex + ": " + types[columnIndex]);
    return types[columnIndex];
    }
    /**
     * Get a column's name by index.
     * @param column the index of the column.
     * @return A {@code String} object containing the column's name.
     */
    @Override
    public String getColumnName(int column) {
    return colNames[column];
    }
    /**
     * Gets all the column names in the table.
     * @return a {@code String} array containing all the column names in the table. 
     */

    public String[] getColumnNames() {
    return this.colNames;
    }

    /**
     * Get the data contained at the specified cell.
     * @param rowIndex the row the cell lies in.
     * @param columnIndex the column the cell lies in.
     * @return an {@code Object} containing the data in the specified cell.
     */

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
//  System.out.println("rowindex: " + rowIndex);
//  System.out.println("columnIndex: " + columnIndex);
//  System.out.println("column length: "+ colNames.length);
//  System.out.println("num rows: "+ + data.size());
//
//  for (int i = 0; i < colNames.length; i++) {
//      System.out.println("Column " + i + ": "+ colNames[i]);
//      
//  }
//  for (int i = 0; i < data.size(); i++) {
//      System.out.println("row " + i + ": " + data.get(i));
//      
//  }
    return this.data.get(rowIndex)[columnIndex];
    }

    /**
     * Gets the number of columns in the table.
     * @return the number of columns in the table.
     */

    @Override
    public int getColumnCount() {
    return colNames.length;
    }

    /**
     * Gets the number of rows in the table.
     * @return the number of rows in the table.
     */

    @Override
    public int getRowCount() {
    return data.size();
    }
    /**
     * Sets the value of the specified cell.
     * @param aValue the new value to set the cell to.
     * @param rowIndex the row the cell lies in.
     * @param columnIndex the column the cell lies in.
     */
    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    Object[] update = this.data.get(rowIndex);
    update[columnIndex] = aValue;
    this.data.set(rowIndex, update);
    fireTableCellUpdated(rowIndex, columnIndex);
    }
    /**
     * Gets an entire row of data.
     * @param row the index of the row to fetch.
     * @return an {@code Object} array containing the row's data.
     */

    public Object[] getRowData(int row) {
    return data.get(row);
    }

    /**
     * Gets all the data types for each column in the table.
     * @return A {@code Class} array containing the types for each column.
     */
    public Class<?>[] getTypes() {
    return types;
    }
    /**
     * Only used in special cases, sets whether the table is editable at all or not.
     * @param addFrame [@code boolean} defining if the table is editable.
     */

    public void setAddFrame(boolean addFrame) {
    this.addFrame = addFrame;
    }

    /**
     * Checks whether the specified cell is editable or not.
     * @param rowIndex The row the cell lies within.
     * @param columnIndex The column the cell within.
     * @return True if the cell is editable, otherwise false.
     */
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
    if (addFrame) {
        if (isAdmin) {
        if (isEditable[columnIndex]) {
            //System.out.println("col " + columnIndex + " editable: true");
            return true;
        } else {
            //System.out.println("col " + columnIndex + " editable: false");
            return false;
        }
        } else {
        //System.out.println("col " + columnIndex + " editable: false");
        return false;
        }
    } else {
        return false;
    }
    }
    /**
     * Adds a row of data to the table.
     * @param data The row to be added.
     */

    public void add(Object[] data) {
    this.data.add(data);
    fireTableRowsInserted(this.data.size(), this.data.size());
    }

    /**
     * Checks if the table is empty.
     * @return true if the table is empty, otherwise false.
     */
    public boolean isDataEmpty() {
    return this.data.isEmpty();
    }
}

注释的位在我创建类时用于调试,这个类已经有一段时间没有改变了,所以它们不再需要了。

编辑:sendToServer() 就在那里,所以我不必每次向流中写入内容时都输入 flush()reset()

static void sendToServer(Object obj) throws IOException {
out.writeObject(obj);
out.flush();
out.reset();
}

其中 out 是与服务器建立连接的ObjectOutputStream

编辑 2:这是我将 SQLTableModel 的实例发送到服务器的地方:

    ConnectionPane.sendToServer("add");
    ConnectionPane.sendToServer(lblTableName.getText());
    ConnectionPane.sendToServer(addTable.getModel());
    String response = (String) ConnectionPane.in.readObject();
    if (response.equals("done")) {
    closeFrame();
    }

这是在服务器端接收它的位:

 else if (cmd.equals("add")) {
    String tableName = (String) client.in.readObject();
    String exec = "add " + tableName + " (";
    SQLTableModel data = (SQLTableModel) client.in.readObject(); //this is where the exception is thrown
    ...

addTable 是一个空表,其中包含用户填写信息的列名。完成后,他们单击添加,然后将表模型发送过来。

【问题讨论】:

    标签: java notserializableexception


    【解决方案1】:

    projectclient.ConnectionPane.sendToServer(ConnectionPane.java:131),您调用某些对象的序列化,最终导致EventListenerList 的序列化。该对象的代码尝试传递序列化java.lang.reflect.Constructor,这就是失败的原因。然而,这是根本原因,而近端原因是反序列化时的异常。序列化因异常而中止,但显然您没有在 write 端检测到它,并且您看到异常已转移到读取端。

    正如您在编辑中解释的那样,sendToServer 序列化其参数。那么问题就出在projectclient.AddRecordFrame.btnAddRecordActionPerformed(AddRecordFrame.java:144) 上,它决定将什么对象发送到服务器。

    如果您确实在尝试序列化整个 SQLTableModel,这显然是一种错误的方法,因为这是一个 Swing GUI 类并且包含大量簿记代码——其中,EventListenerList 在您的情况下失败了.您可能只想传输表的内容,这是您控制的集合 — ArrayList&lt;Object[]&gt; data。仅将该集合发送到服务器。

    【讨论】:

    • SQLTableModel 是我自己的类,除非我误解了你。我还需要表的名称、列和类型,这就是我将整个模型发送过来的原因,因为它更容易处理。有没有办法知道是哪个EventListener 导致了问题?我在发送数据后立即关闭包含表格的表单,因此无论如何我都可以删除所有EventListeners。
    • 是的,SQLTableModel 是您的课程,但仅限于您实施的部分,因为它也是 AbstractTableModel。请不要走你现在要走的路——要么制作一个单独的 DTO,其中包含你需要的所有模型,要么只是将它们一个一个地交给服务器。使AbstractTableModel 的序列化成功是不值得的。
    • 谢谢,我改一下。虽然在 API 文档中AbstractTableModel 实现了可序列化,所以我还是有点困惑。抱歉,如果我犯了愚蠢的错误,我使用 Java 的时间不长。
    • 是的,关于 ATM 可序列化的说法是正确的。现在你让我想知道......我的直觉告诉我这是一种错误的序列化方法,但它确实是可序列化的。您可以访问listenerList 属性(它是protected)并查看那里发生了什么,但您可能会发现那里的任何东西都应该留在那里,这样您就回到了起点。
    【解决方案2】:

    只要看看你的堆栈跟踪,这行就说明了:

    at javax.swing.event.EventListenerList.writeObject(EventListenerList.java:257)
    

    换句话说,AbstractTableModel 保留了任意事件侦听器对象的列表,这些对象可以是任何类,Serializable 或不是,当AbstractTableModel 被序列化时,会尝试序列化这些事件听众也是。当听众自己不是Serializable 时,这将失败。这或许可以解释为什么这是一个暂时性问题,因为事件侦听器可以随着程序的运行来来去去。

    但肯定还有其他问题:特别是,您没有对序列化data 数组的内容进行任何特殊安排,并且不能保证它包含的对象本身就是Serializable

    【讨论】:

    • 我没有向表模型或类似的东西添加任何侦听器。有没有办法列出对象上的所有事件侦听器?也许那时我可以看到是哪一个导致了这个问题。我仍然不明白为什么它也不会每次都发生。编辑:只有可序列化的对象可以在数据数组中。数据输入通过 Class> 数组确保这一点。表中只能放入包装类和 SQL 日期、时间和时间戳包装类。
    猜你喜欢
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 2012-07-10
    相关资源
    最近更新 更多