Java SonarQube 规则鱿鱼 :S1948 - how to use serializable lists without being bound to e. g。数组列表

标签 java serialization arraylist sonarqube

SonarQube 规则 squid:S1948要求可序列化类的所有字段都是可序列化的或 transient 的。 Another rule声明宁愿使用接口(interface)而不是实现类型。

当我有一个

public class myClass implements Serializable
{
  List<String> names;
  ...
}

然后 names应该是 List<String>比例如ArrayList<String> .但是规则 S1948 告诉我们 List不可序列化。

解决方案一目了然:定义一个 interface SerializableList - 可能是这样的:

public interface SerializableList<E> extends List<E>, Serializable
{
}

如果我们声明 names成为一个

  SerializableList<String> names;

来自规则 S1948 的警告消失了,但是赋值 names = new ArrayList<String>();结果 Type mismatch: cannot convert from ArrayList<String> to SerializableList<String> .

两个问题:

  • 为什么我可以申报List<String> names = new ArrayList<String>();没有警告也不需要投,但不能声明 SerializableList<String> names = new ArrayList<String>(); ?我想知道,因为ArrayList<E> implements List<E>, Serializable, ... - 为什么不是 SerializableList
  • 如何申报names以 S1948 和其他规则都不会发出警告的方式,但我仍然可以自由使用任何类型的 List那也是Serializable (如 ArrayList ,...)并且不需要显式转换。

感谢任何提示。

最佳答案

why can I declare List<String> names = new ArrayList<String>(); without a warning nor need to cast, but cannot declare SerializableList<String> names = new ArrayList<String>();? I wonder, because ArrayList<E> implements List<E>, Serializable, ... - why isn't it a SerializableList?

您想使用 Java 中不存在的结构/功能(“分组接口(interface)”)。现在你引入了一个新类型 SerializableList扩展其他类型:

List    Serializable
  ↑          ↑
SerializableList

ArrayList还扩展了 SerializableList 的两种父类型:

List   Serializable
  ↑         ↑
   ArrayList

但是SerializableList之间没有联系和 ArrayList .如果我们定义一个新类型:

public class SerializableListImpl extends ArrayList implements SerializableList

然后我们有:

   --------→ List ←---------
   |                       |
   |  --→ Serializable ←-- |
   | |                   | |
ArrayList          SerializableList
      ↑                 ↑
      SerializableListImpl 

最后:

List serializableList = new SerializableListImpl();
System.out.println(serializableList instanceof List); // true
System.out.println(serializableList instanceof Serializable); // true
System.out.println(serializableList instanceof ArrayList); // true
System.out.println(serializableList instanceof SerializableList); // true

List arrayList = new ArrayList();
System.out.println(arrayList instanceof List); // true
System.out.println(arrayList instanceof Serializable); // true
System.out.println(arrayList instanceof ArrayList); // true
System.out.println(arrayList instanceof SerializableList); // false ← not in the hierarchy

how to declare names in a way that neither S1948 nor the other rule will give a warning, but I can still be free to use any kind of List that is also Serializable (like ArrayList, ...) and without need for an explicit cast.

你不能。不是每个 List 的实现接口(interface)也必须是Serializable .任何人都可以定义新类型:

public class MyList implements List {
    ...
}

分配给 names字段然后:

List myList = new MyList();
System.out.println(serializableList instanceof List); // true
System.out.println(serializableList instanceof Serializable); // false ← not in the hierarchy

正如我在顶部所写的“分组界面”这样的功能:

SerializableList == List<String>&&Serializable

不存在,因此您必须将问题标记为 Won't Fix .

关于Java SonarQube 规则鱿鱼 :S1948 - how to use serializable lists without being bound to e. g。数组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49289500/

相关文章:

java - 在 intellij 中运行参数化 junit 测试的单个场景

java - SSL VPN 连接到使用 Java 的 Fortinet 防火墙

android - 如何从 retrofit 响应中获取 JSON ARRAY 和 JSON 对象响应?

java - ArrayList:当你有多个 setter 时如何设置 arraylist.set

java - Spring bean 实例化顺序

java - @重写困惑

Kotlin commonMain 与 java.io.Serializable

java - readObject 的 EOF 异常

java - 如何复制数组或数组列表

loops - 为什么我不能将哈希表存储在数组列表中?