如何序列化可作为自身类型参数的泛型类?SonarLint警告处理
泛型序列化与SonarLint误报的解决经历
最近我在实现一个带泛型的可序列化类Pair<T>时碰到了一个奇怪的SonarLint警告,这里把问题和解决过程分享给大家:
需求说明
我需要实现的Pair<T>要满足这些要求:
- 是可作为自身类型参数的泛型类
- 实现
Comparable<Pair<T>>和Serializable接口 - 类型参数
T必须同时实现Comparable<? super T>和Serializable,以此保证Pair<T>的可序列化能力
另外还有一个子类PairCoord,继承自Pair<Integer>并实现Serializable接口。
遇到的诡异警告
明明已经给T加上了Serializable的约束,但SonarLint还是对Pair类里的first和last两个字段抛出严重警告:
可序列化类中的字段需为transient或可序列化
初始代码
Pair类实现
public class Pair<T extends Comparable<? super T> & Serializable> implements Comparable<Pair<T>>, Serializable { private static final long serialVersionUID = 5797102044530257848L; private T first; private T last; public Pair(T first, T last) { this.first = first; this.last = last; } public Pair() { } // 其他业务方法 }
PairCoord子类实现
public class PairCoord extends Pair<Integer> implements Serializable { private static final long serialVersionUID = 8389593640798914292L; public PairCoord(int first, int last) { super(first, (last + 8) % 8); // 注释说明: // 由于3个方块均为循环结构,编号0的前一个节点应为编号-1 // 但编号-1不存在,而(-1 mod 8)=7 // 问题在于%是欧几里得除法的余数而非模运算 // 因此给last加8确保运算数为正,对于x>=0,%表现得像模运算,从而得到0-7之间的正确节点编号 } }
解决方法
在Joachim Sauer和Viral Lalakia的提示下,我尝试交换了T约束里两个接口的顺序——把Serializable放在Comparable<? super T>前面,没想到SonarLint的警告直接消失了!
修改后的Pair类泛型声明部分:
public class Pair<T extends Serializable & Comparable<? super T>> implements Comparable<Pair<T>>, Serializable { // 其余代码完全不变 }
显然这个警告是SonarLint的误报,只是对泛型约束的顺序敏感导致的。
内容的提问来源于stack exchange,提问作者G-Crow
相关产品推荐
相关产品推荐

