为什么我的对象的字段在使用 objectInputStream.readObject() 反序列化后设置为默认值?

Why are my object's fields set to default after deserializing with objectInputStream.readObject()?

在 Java 中,我有一个简单的 class,其中包含三个 public(原始)字段,如下所示:

public class MyObject implements Serializable {
    public volatile float x, y, z;

    public MyObject() {
        this(0, 0, 0);
    }

    public MyObject(float x, float y, float z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public void set(float x, float y, float z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public void set(MyObject other) {
        set(other.x, other.y, other.z);
    }
}

我像这样将对象写入对象输出流:

public void write(MyObject myObject) {
    try {
        mObjectOutStream.writeObject(myObject);
        mObjectOutStream.flush();

        Log.d(TAG, "wrote myObject.x as:" + myObject.x);
        Log.d(TAG, "wrote myObject.y as:" + myObject.y);
        Log.d(TAG, "wrote myObject.z as:" + myObject.z);
    } catch (IOException) {
        Log.e(TAG, "Exception during write", e);
    }
}

而且,我在单独的线程中使用阻塞调用从对象输入流中读取对象,如下所示:

public void run() {
    while (true) {
        try {
            MyObject myObject = (MyObject) mObjectInStream.readObject();

            Log.d(TAG, "read myObject.x as:" + myObject.x);
            Log.d(TAG, "read myObject.y as:" + myObject.y);
            Log.d(TAG, "read myObject.z as:" + myObject.z);
        } catch (IOException) {
            Log.e(TAG, "Exception during read", e);
        } catch (ClassNotFoundException) {
            Log.e(TAG, "Exception during read", e);
        }
    }
}

不知何故,我的日志显示如下:

BluetoothService: wrote myObject.x as: 0.37361085
BluetoothService: wrote myObject.y as: 0.87006456
BluetoothService: wrote myObject.z as: 1.7877682
BluetoothService: read myObject.x as: 0.0
BluetoothService: read myObject.y as: 0.0
BluetoothService: read myObject.z as: 0.0

我已经尝试将字段声明为易失性以确保它们是线程安全的,并尝试为 MyObject class 实现 readObject 和 writeObject 方法,但是 none 这有帮助。

我怀疑(希望)我遗漏了一些简单的东西,有人可以指出。

如果相关,我在 Android 上使用蓝牙插座。我已成功发送 String 对象,但使用 byte[],就像 Android 示例代码中的 BluetoothChat 示例一样。我无法发送我的可序列化对象。

有人可以在这里为我指明正确的方向,或者可以给我一些有关如何解决此问题的提示吗?我不知道如何缩小问题范围,超出我目前记录的范围。

如果您不是第一次将此 MyObject 写入流,则需要在两次写入之间使用 ObjectOutputStream.reset(),或者 ObjectOutputStream.writeUnshared(). 请参阅 Javadoc 了解原因。

注意,当您捕捉到 EOFException, 并且可能在任何其他 IOException 上时,您的循环应该终止。