Java 序列化双括号初始化映射
有人能解释下面例子中的序列化问题吗。我有两个相同的(equals返回true)映射-一个用标准方式初始化,另一个用双括号初始化。第二个无法序列化(抛出NotSerializableException) 在这个演示中,Java 序列化双括号初始化映射,java,Java,有人能解释下面例子中的序列化问题吗。我有两个相同的(equals返回true)映射-一个用标准方式初始化,另一个用双括号初始化。第二个无法序列化(抛出NotSerializableException) 在这个演示中,Map m=newhashmap(){是一个匿名的内部类,您可以使用System.out.println(m.getClass())检查m的类 public class Utilt implements Serializable { private static final
Map m=newhashmap(){
是一个匿名的内部类,您可以使用System.out.println(m.getClass())
检查m的类
public class Utilt implements Serializable {
private static final long serialVersionUID = -7271914225876022793L;
@Test
public void UtilTest() throws IOException, ClassNotFoundException {
Map<String, Object> m = new HashMap<String, Object>(){
private static final long serialVersionUID = 1L;
{
put("test", "String");
}};
Map<String, Object> m2 = new HashMap<String, Object>();
m2.put("test", "String");
Assert.assertEquals(m, m2); // true
Assert.assertTrue(m.equals(m2)); // true
Assert.assertEquals(Utils.deserialize(Utils.serialize(m2)), m2); // ok
Assert.assertEquals(Utils.deserialize(Utils.serialize(m)), m);
}
}
public类Utilt实现可序列化{
私有静态最终长serialVersionUID=-7271914225876022793L;
@试验
public void UtilTest()引发IOException,ClassNotFoundException{
Map m=新的HashMap(){
私有静态最终长serialVersionUID=1L;
{
放置(“测试”、“字符串”);
}};
Map m2=新的HashMap();
m2.放置(“测试”、“字符串”);
Assert.assertEquals(m,m2);//true
Assert.assertTrue(m.equals(m2));//true
Assert.assertEquals(Utils.deserialize(Utils.serialize(m2)),m2);//确定
Assert.assertEquals(Utils.deserialize(Utils.serialize(m)),m);
}
}
第二个无法序列化(抛出NotSerializableException)
这是因为您正在非序列化类中的非静态方法中初始化映射
双括号初始化实际上只是用实例初始值设定项定义一个匿名类。非静态上下文中的匿名类捕获对封闭实例的引用
如果该类不可序列化,则无法序列化匿名类实例。此代码似乎位于单元测试类中;此类可序列化的情况非常罕见
老实说,最简单的解决办法就是避免双大括号初始化。这是一种语法上的捏造,太聪明了,不利于自己
但是,如果您真的坚持使用它,您可以简单地用静态方法进行初始化
static Map<String, Object> doubleBrace() {
return new HashMap<String, Object>(){
private static final long serialVersionUID = 1L;
{
put("test", "String");
}};
}
静态映射双括号(){
返回新的HashMap(){
私有静态最终长serialVersionUID=1L;
{
放置(“测试”、“字符串”);
}};
}
但这在某种程度上破坏了首先使用双大括号初始化的简洁性。确切的异常文本是什么?并尝试将字段设置为静态-因为您正在创建一个匿名内部类来初始化映射,您正在拉入当前对象实例,而它不是serializabke。确切的异常文本应该l您可以知道哪个类不是序列化类。双括号初始化通常是这样。您可以检查它们的
hashCode
是否相同。如果它们不相同,则不可能相等。感谢您的回答!您可能需要进一步了解为什么创建匿名内部类会使其不可序列化。
public class Utilt implements Serializable {
private static final long serialVersionUID = -7271914225876022793L;
@Test
public void UtilTest() throws IOException, ClassNotFoundException {
Map<String, Object> m = new HashMap<String, Object>(){
private static final long serialVersionUID = 1L;
{
put("test", "String");
}};
Map<String, Object> m2 = new HashMap<String, Object>();
m2.put("test", "String");
Assert.assertEquals(m, m2); // true
Assert.assertTrue(m.equals(m2)); // true
Assert.assertEquals(Utils.deserialize(Utils.serialize(m2)), m2); // ok
Assert.assertEquals(Utils.deserialize(Utils.serialize(m)), m);
}
}
static Map<String, Object> doubleBrace() {
return new HashMap<String, Object>(){
private static final long serialVersionUID = 1L;
{
put("test", "String");
}};
}