Java 对象在重新序列化后是否可能具有不同的字节大小?
在Java中,我创建了一个对象,将其序列化为一个长度为642字节的数组,然后将其返回到一个对象中,序列化该对象,得到一个长度为651字节的数组。这是怎么发生的,为什么发生的?我认为对象的长度应该与重复序列化一致,因为在我序列化和反序列化的其他对象中,长度是相同的。请注意,在随后的反序列化和重新序列化之后,长度保持在651字节 这是我的密码:Java 对象在重新序列化后是否可能具有不同的字节大小?,java,sockets,serialization,stream,Java,Sockets,Serialization,Stream,在Java中,我创建了一个对象,将其序列化为一个长度为642字节的数组,然后将其返回到一个对象中,序列化该对象,得到一个长度为651字节的数组。这是怎么发生的,为什么发生的?我认为对象的长度应该与重复序列化一致,因为在我序列化和反序列化的其他对象中,长度是相同的。请注意,在随后的反序列化和重新序列化之后,长度保持在651字节 这是我的密码: PrivateIPV4_Reliable object = new PrivateIPV4_Reliable(); final byte[] data =
PrivateIPV4_Reliable object = new PrivateIPV4_Reliable();
final byte[] data = ByteArrays.ObjectToByteArray(object);
AppTester.print("Serialized an PrivateIPV4_Reliable of size: " + data.length);
// 642 bytes
PrivateIPV4_Reliable deSerialzed = (PrivateIPV4_Reliable) ByteArrays.MakeByteArrayIntoObject(data);
byte[] deserializedBytes = ByteArrays.ObjectToByteArray(deSerialzed);
AppTester.print("Reserialized it into object of length: " + deserializedBytes.length + "\n");
// 651 bytes
// Why does the object get bigger after re-serialization?
// This size increase did not happen with another object that I serialized and de-serialized.
*更新1*
以下是十六进制格式的字节数组:
第一次序列化后的字节数组:(长度:642)
ACED000573720022436F72655F52656C6961626C652E5076617465495056345F5265961626C65001691657B307FB102000349000D7950726976617465506F72744A00166D7954696D65466D65466E7474616E5F5B00136D79507276617464646464767365735F7400175B4C676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676657441647265733B38E6AD91E5D9DA880200007870000000005737200156A6176612E657442E4965744364647265735F7C208152C2C802103000549008736F70655F69645A000C73636F70655F69645F73655F7065745A001073636F70655F6966666E616D6555F73744C0006666666E616D6557400124C676616A6616C6616C6616E67767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676764726573732D9B57AF9FE3EBDB0300034900076164647265734900066616D696C794C00086F73744E616D671007E0006787000000002707800000027078000000301010740005776C616E30757200025B42ACF317F8060854E002000078700000002602030A2E0A9D900000000000000457871007E0005000000000270000000070107E000A77E000B000001026020030A9D90A28869FF31E7307710E0005000000000270780000003010171007E000A75710007E000B0000010FE800000000000A28869FFFE31331E787371007E00050000000002707800000030171007E000A757007E000B000001026020030A2E0A9D90E9958CBC64D3B80B787371007E0008C0A8014F000000027078
第二次序列化后的字节数组:(长度:651)
ACED000573720022436F72655F52656C6961626C652E5076617465495056345F5265961626C65001691657B307FB102000349000D7950726976617465506F72744A00166D7954696D65466D65466E7474616E5F5B00136D79507276617464646464767365735F7400175B4C676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676657441647265733B38E6AD91E5D9DA880200007870000000005737200156A6176612E657442E4965744364647265735F7C208152C2C802103000549008736F70655F69645A000C73636F70655F69645F73655F7065745A001073636F70655F6966666E616D6555F73744C0006666666E616D6557400124C676616A6616C6616C6616E67767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676764726573732D9B57AF9FE3EBDB0300034900076164647265734900066616D696C794C00086F73744E616D671007E0006787000000002707800000027078000000301010740005776C616E30757200025B42ACF317F8060854E002000078700000002602030A2E0A9D900000000000000457871007E0005000000000270000000070701700000000070707070707070707070701007E000B000001026030A290A28869FE317371007E00050000000000000002707800000030101740005776C616E307571007E000B0000010FE800000000000A28869FFFE31331E787371007E000500000000027078000000301740005776C616E307571007E000B0000160203A2E0A9D90E9958CBC64D3B80B787371007E0008C0A8014F000000027078
第三次序列化后的字节数组(长度:651,与第二次序列化相同)
*更新2*
以下是正在序列化/反序列化的对象:
package Core_Reliable;
import Utilities.AppTester;
import Utilities.ByteArrays;
import java.io.Serializable;
import java.net.InetAddress;
/**
* @author johnmichaelreed2
*/
public final class PrivateIPV4_Reliable implements Serializable {
private static final long serialVersionUID = 6352314532134833L;
private final InetAddress[] myPrivateAddresses_;
private final int myPrivatePort;
private final long myTimeOfInstantiation_;
public PrivateIPV4_Reliable(InetAddress privateIPs[], int privatePort) {
AppTester.check(privateIPs != null, "No null values in initializer.");
this.myPrivateAddresses_ = privateIPs;
this.myPrivatePort = privatePort;
this.myTimeOfInstantiation_ = System.currentTimeMillis();
}
public boolean deepEquals(PrivateIPV4_Reliable other) {
return ByteArrays.deepEquals(this, other);
}
public InetAddress getCopyOfInetAddressNumber(int index) {
InetAddress copy = ByteArrays.tryDeepCopy(this.myPrivateAddresses_[index]);
AppTester.check(copy != null, "Failed to deep copy my InetAddress");
AppTester.check(copy instanceof InetAddress, "The copy isn't an InetAddress");
return copy;
}
public InetAddress[] getInetAddressesCopy() {
AppTester.check(myPrivateAddresses_ != null, "No null private address lists.");
return ByteArrays.tryDeepCopy(myPrivateAddresses_);
}
public int getPrivatePort() {
return myPrivatePort;
}
public long getTimeAtInstantiation() {
return myTimeOfInstantiation_;
}
}
以下是我用于序列化的方法:
public static byte[] ObjectToByteArray(final Object object) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.flush();
oos.writeObject(object);
oos.flush();
oos.close();
// get the byte array of the object
byte[] obj = baos.toByteArray();
baos.flush();
baos.close();
return obj;
} catch (Exception e) {
AppTester.printEx(e);
System.exit(-78);
return null;
}
}
public static Object makeByteArrayIntoObject(byte[] data) {
AppTester.check(data != null, "Null data");
Object to_return = null;
try(ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) {
try {
to_return = ois.readObject();
} catch (ClassNotFoundException cnfe) {
AppTester.printEx(cnfe);
} catch(StreamCorruptedException sce) {
AppTester.printEx(sce);
}
} catch (IOException ioe) {
AppTester.printEx(ioe);
} finally {
return to_return;
}
}
以下是我用于反序列化的方法:
public static byte[] ObjectToByteArray(final Object object) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.flush();
oos.writeObject(object);
oos.flush();
oos.close();
// get the byte array of the object
byte[] obj = baos.toByteArray();
baos.flush();
baos.close();
return obj;
} catch (Exception e) {
AppTester.printEx(e);
System.exit(-78);
return null;
}
}
public static Object makeByteArrayIntoObject(byte[] data) {
AppTester.check(data != null, "Null data");
Object to_return = null;
try(ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) {
try {
to_return = ois.readObject();
} catch (ClassNotFoundException cnfe) {
AppTester.printEx(cnfe);
} catch(StreamCorruptedException sce) {
AppTester.printEx(sce);
}
} catch (IOException ioe) {
AppTester.printEx(ioe);
} finally {
return to_return;
}
}
其中“AppTester”是我的自定义日志记录/调试/断言类。(请参阅)确定问题原因的唯一方法是使用某种工具将两个版本的序列化作为字节流进行比较,然后根据规范说明手动反转序列化 然而,一种可能性是在原始序列化和重新序列化之间对类
PrivateIPV4\u
进行了“二进制兼容”更改。如果您怀疑该类有多个版本,那么这就可以解释了
请注意,Java对象序列化协议/格式并不保证序列化是相同的。确定问题原因的唯一方法是使用某种工具将序列化的两个版本作为字节流进行比较,然后根据规范说明手动反转序列化 然而,一种可能性是在原始序列化和重新序列化之间对类
PrivateIPV4\u
进行了“二进制兼容”更改。如果您怀疑该类有多个版本,那么这就可以解释了
请注意,Java对象序列化协议/格式不能保证序列化是相同的。对此有很多可能的解释。向我们展示正在被序列化/反序列化的类。正在被序列化/反序列化的类非常不引人注目,它甚至没有任何瞬态变量或任何特殊的序列化方法。它只包含一个java.net.InetAddress的ArrayList、一个字节数组和一个int。我将向您展示它。我添加了代码。。。您是否认为Netbeans使用了错误的类版本?我一直有一个错误,因为IDE存储或使用旧/错误版本的类时出现了类未找到异常。对此有很多可能的解释。向我们展示正在被序列化/反序列化的类。正在被序列化/反序列化的类非常不引人注目,它甚至没有任何瞬态变量或任何特殊的序列化方法。它只包含一个java.net.InetAddress的ArrayList,一个字节数组