out*_*ind 4 java serialization arraylist sonarqube
SonarQube 规则鱿鱼:S1948要求可序列化类的所有字段都是可序列化的或瞬态的。另一条规则指出,应该使用接口而不是实现类型。
当我有一个
public class myClass implements Serializable
{
List<String> names;
...
}
Run Code Online (Sandbox Code Playgroud)
那么names应该是 aList<String>而不是 eg ArrayList<String>。但规则 S1948 告诉我们这List是不可序列化的。
乍一看,解决方案:定义一个interface SerializableList- 可能像这样:
public interface SerializableList<E> extends List<E>, Serializable
{
}
Run Code Online (Sandbox Code Playgroud)
如果我们声明names是一个
SerializableList<String> names;
Run Code Online (Sandbox Code Playgroud)
规则 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, ...- 为什么它不是 a SerializableList?names以 S1948 和其他规则都不会发出警告的方式声明,但我仍然可以自由使用任何类型的List(Serializable例如ArrayList,...)并且不需要显式强制转换。感谢您的任何提示。
\n\n\n为什么我可以
\nList<String> names = new ArrayList<String>();在没有警告的情况下声明,也不需要强制转换,但不能声明SerializableList<String> names = new ArrayList<String>();?我想知道,因为ArrayList<E> implements List<E>, Serializable, ...- 为什么它不是一个SerializableList?
您想要使用 Java 中不存在的结构/功能(“分组接口”)。现在您引入了一种SerializableList扩展其他类型的新类型:
List Serializable\n \xe2\x86\x91 \xe2\x86\x91\nSerializableList\nRun Code Online (Sandbox Code Playgroud)\n\nArrayList还扩展了 的两个父类型SerializableList:
List Serializable\n \xe2\x86\x91 \xe2\x86\x91\n ArrayList\nRun Code Online (Sandbox Code Playgroud)\n\n但它们之间没有联系SerializableList和ArrayList。如果我们定义一个新类型:
public class SerializableListImpl extends ArrayList implements SerializableList\nRun Code Online (Sandbox Code Playgroud)\n\n那么我们有:
\n\n --------\xe2\x86\x92 List \xe2\x86\x90---------\n | |\n | --\xe2\x86\x92 Serializable \xe2\x86\x90-- |\n | | | |\nArrayList SerializableList\n \xe2\x86\x91 \xe2\x86\x91\n SerializableListImpl \nRun Code Online (Sandbox Code Playgroud)\n\n最后:
\n\nList serializableList = new SerializableListImpl();\nSystem.out.println(serializableList instanceof List); // true\nSystem.out.println(serializableList instanceof Serializable); // true\nSystem.out.println(serializableList instanceof ArrayList); // true\nSystem.out.println(serializableList instanceof SerializableList); // true\n\nList arrayList = new ArrayList();\nSystem.out.println(arrayList instanceof List); // true\nSystem.out.println(arrayList instanceof Serializable); // true\nSystem.out.println(arrayList instanceof ArrayList); // true\nSystem.out.println(arrayList instanceof SerializableList); // false \xe2\x86\x90 not in the hierarchy\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n如何以 S1948 和其他规则都不会发出警告的方式声明名称,但我仍然可以自由使用任何类型的名称
\nList(Serializable例如ArrayList,...)并且不需要显式强制转换。
你不能。并非每个List接口的实现都必须如此Serializable。任何人都可以定义一个新类型:
public class MyList implements List {\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n\n分配给该names字段,然后:
List myList = new MyList();\nSystem.out.println(serializableList instanceof List); // true\nSystem.out.println(serializableList instanceof Serializable); // false \xe2\x86\x90 not in the hierarchy\nRun Code Online (Sandbox Code Playgroud)\n\n正如我在顶部所写的“分组界面”这样的功能:
\n\nSerializableList == List<String>&&Serializable\nRun Code Online (Sandbox Code Playgroud)\n\n不存在,因此您必须将问题标记为Won\'t Fix。