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 declareSerializableList<String> names = new ArrayList<String>();
? I wonder, becauseArrayList<E> implements List<E>, Serializable, ...
- why isn't it aSerializableList
?
您想使用 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 alsoSerializable
(likeArrayList
, ...) 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/