![](/img/trans.png)
[英]Fields in a “Serializable” class should either be transient or serializable squid : S1948
[英]Java SonarQube rule squid:S1948 - how to use serializable lists without being bound to e.g. ArrayList
SonarQube 规则squid:S1948要求可序列化类的所有字段都是可序列化的或瞬态的。 另一条规则规定宁可使用接口而不是实现类型。
当我有一个
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
,但我仍然可以自由使用任何类型的List
也是可Serializable
的(如ArrayList
,......)并且不需要显式转换.感谢您的任何提示。
为什么我可以声明
List<String> names = new ArrayList<String>();
没有警告也不需要转换,但不能声明SerializableList<String> names = new ArrayList<String>();
? 我想知道,因为ArrayList<E> implements List<E>, Serializable, ...
- 为什么它不是SerializableList
?
您想要使用 Java 中不存在的结构/功能(“分组接口”)。 现在您引入了一个新类型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
如何以 S1948 和其他规则都不会发出警告的方式声明名称,但我仍然可以自由使用任何类型的
List
也是可Serializable
的(如ArrayList
,......)并且不需要显式转换.
你不能。 并非List
接口的每个实现都必须也是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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.