为什么我的对象的字段在使用 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
上时,您的循环应该终止。
在 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
上时,您的循环应该终止。