Java为什么Map的Map(例如:Map <string,map <string,string>&gt;)不可序列化

时间:2017-01-15 09:01:49

标签: java serialization hashmap sonarqube

我们在HashMap中使用JDK 1.7,我在使用 SonarQube 进行代码审核时遇到了一些问题。

请考虑以下样本:

public class SerializationTest implements  Serializable {

   private Map<String,String> test1=new HashMap<>(); //Serializeable
   private Map<ANEnum,String> test2=new HashMap<>(); //Serializeable
   private Map<String,ASerializeableObject> test3=new HashMap<>();  //Serializeable 

   private Map<String,Map<String,String>> test4=new HashMap<>(); //Not Serializeable
   private Map<ANEnum,Map<String,String>> test5=new HashMap<>(); //Not Serializeable
   private Map<String,Map<String, ASerializeableObject>> test6=new HashMap<>(); //Not Serializeable

声纳标记的最后三个HashMap不是serializeable。声纳误差为(Make "test4" transient or serializable

据我猜测,如果HashMap的关键字和值为serializeable,则serializeableHashMap。但似乎如果我将HashMap值设置为另一个HashMap,则原始serializeable根本不会是runtime

这个声纳问题是否正确?如果是我该怎么办呢?!

1 个答案:

答案 0 :(得分:5)

让我们一个接一个地看到每一行:

private Map<String,String> test1=new HashMap<>();

键类型String是可序列化的。值类型String是可序列化的。具体的Map类型HashMap是可序列化的。所以一切都是可序列化的。

private Map<ANEnum,String> test2=new HashMap<>(); 

密钥类型ANEnum是可序列化的。值类型String是可序列化的。具体的Map类型HashMap是可序列化的。所以一切都是可序列化的。

private Map<String,ASerializeableObject> test3=new HashMap<>();

键类型String是可序列化的。值类型ASerializeableObject是可序列化的。具体的Map类型HashMap是可序列化的。所以一切都是可序列化的。

private Map<String,Map<String,String>> test4=new HashMap<>();

键类型String是可序列化的。具体的Map类型HashMap是可序列化的。 值类型Map不是必然可序列化。 Map的一些具体实现(如HashMap)是可序列化的。其他一些则不是。因此Sonar无法保证此字段是可序列化的,并发出警告。如果您确定只将可序列化地图存储为值,则没问题。如果存储不可序列化的映射,则序列化将在运行时失败。

private Map<ANEnum,Map<String,String>> test5=new HashMap<>(); //Not Serializeable

与之前相同的解释

private Map<String,Map<String, ASerializeableObject>> test6=new HashMap<>();

与之前相同的解释

请记住,声纳只是一种工具,它有时会有所帮助,有时会妨碍它。你应该掌控,并决定警告是否应该让你改变一切。