前言:因公司需求使用sonarlint做漏洞排查,整理了一批问题及修改方法,如有错误的地方可以留言指正
1.Fields in a "Serializable" class should either be transient or serializable
说明:类属性中存在不能被序列化的属性,一般是对象
如:
public class Address {//...}
public class Person implements Serializable {
private static final long serialVersionUID = 1905122041950251207L;
private Address address;
private String name;
}
解决:在对象中做序列化操作并给序列化标识id
如:
public class Address implements Serializable {
private static final long serialVersionUID = 2405172041950251807L;
}
无法进行序列话的属性前加上 transient
关键词做忽略序列化操作
如:
public class Person implements Serializable {
private static final long serialVersionUID = 1905122041950251207L;
private transient Address address;
private String name;
}
2.Generic exceptions should never be thrown
说明:不要主动引发一般异常
如:
public static <T> ApiResult<T> fail(ApiCode apiCode, T data){
if (ApiCode.SUCCESS == apiCode){
throw new RuntimeException("失败结果状态码不能为" + ApiCode.SUCCESS.getCode());
}
return result(apiCode,data);
}
解决:使用自定义业务异常或直接不使用通过其他方式处理
如:
public static <T> ApiResult <T> fail(ApiCode apiCode, T data){
if (ApiCode.SUCCESS == apiCode){
throw new BusinessException("失败结果状态码不能为" + ApiCode.SUCCESS.getCode());
}
return result(apiCode,data);
}
3.Methods should not be empty
说明:不要存在空方法
如:
public Assert() {
}
解决:填写方法注释内容或私有化构造器
private Assert() {
throw new IllegalStateException("Assert class");
}
4."static" base class members should not be accessed via derived types
说明:为了代码清晰起见,永远不要使用子类的名称访问父类的静态成员。这样做会造成混淆,并且可能会导致存在两个不同的静态成员的错觉
解决:直接使用父类的属性或者方法进行作业
5.Utility classes should not have public constructors
说明:工具类里面不能有public的构造函数,需要构建一个private 的构造函数
解决:将工具类中的public构造函数换成private
如:
private Assert() {
throw new IllegalStateException("Assert class");
}
6.Raw types should not be used
说明:不应使用原始类型
如:
for (List list : lists) {
if (list==null || list.size() ==0){
...
}
}
解决:范型写完整,如果不指定可以写问号
如:
for (List <String> list : lists) {
if (list==null || list.size() ==0){
...
}
}
或
for (List<?> list : lists) {
if (list==null || list.size() ==0){
...
}
}
7.Nested blocks of code should not be left empty
说明:嵌套代码块不应留空
解决:根据实际需求去除或者填充代码块
8.Instance methods should not write to "static" fields
说明:实例方法不应该写入“静态”字段
如:
protected static ApplicationContext context;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
解决:将非静态方法中对静态方法赋值的语句,单独封装一个静态方法然后让非静态方法调用
如:
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
setContext(applicationContext);
}
private static void setContext(ApplicationContext applicationContext){
context = applicationContext;
}
9.Silly equality checks should not be made
说明:不应该进行愚蠢的等式检查,非同类型的对象equal或等式判断
解决:删除更换愚蠢的比较
10.Standard outputs should not be used directly to log anything
说明:标准输出不应直接用于记录任何内容
解决:用日志记录代替标准输出
11.Constant names should comply with a naming convention
说明:常量名称应符合命名约定
解决:常量命名因全大写,单词之间用下划线间隔
12.String literals should not be duplicated
说明:字符串文字不应重复
如:
public void run() {
prepare("action1");
execute("action1");
release("action1");
}
解决:将字符串抽取为常量
如:
private static final String ACTION_1 = "action1";
public void run() {
prepare(ACTION_1 );
execute(ACTION_1 );
release(ACTION_1 );
}
13.Cognitive Complexity of methods should not be too high
说明:方法的认知复杂性不应太高,if else过多
解决:对业务逻辑进行拆分抽取成单独子方法
14.Sections of code should not be commented out
说明:代码部分不应注释掉
解决:根据实际需求修改该部分写法
15.Constructors should not be used to instantiate "String", "BigInteger", "BigDecimal" and primitive-wrapper classes
说明:构造函数不应用于实例化“String”、“BigInteger”、“BigDecimal”和基元包装类
解决:使用封装类的.valueOf方法进行转换
16.Unused method parameters should be removed
说明:应删除未使用的方法参数
解决:删除未使用的方法参数
17.Class names should not shadow interfaces or superclasses
说明:类名不应隐藏接口或超类
解决:修改类名不要和父类相同命名
18.Non-thread-safe fields should not be static
说明:非线程安全字段不应是静态的
解决:非线程安全字段视情况做局部变量或做其他处理
19.Unused assignments should be removed
说明:应删除未使用的分配
解决:删除未使用,无用的对象
20.Empty arrays and collections should be returned instead of null
说明:应返回空数组和集合,而不是null
解决:返回空数组和集合
21.Unused "private" fields should be removed
说明:应删除未使用的“私有”字段
解决:删除未使用的“私有”字段
22."BigDecimal(double)" should not be used
说明:不应使用“BigDecimal(double)”
解决:数据转换使用引用类的.valueOf()方法进行转换
23.Local variables should not shadow class fields
说明:局部变量不应该和类字段同名
解决:修改命名
24."String#replace" should be preferred to "String#replaceAll"
说明:应首选“String#replace”而不是“String#replaceAll”
解决:简单替换逻辑使用replace效能更高
25.Resources should be closed
说明:(实现 close-able 接口或其超级接口 autoclose-able 的连接、流、文件和其他)类在使用后需要关闭。必须在 finally 块 else 中执行 close 调用,否则将无法执行调用
解决:在 finally 块中将资源关闭
26.Printf-style format strings should be used correctly
说明:Printf 启用 style 格式字符串应该被正确使用(Printf-style 的字符串是在运行时解释的,而不是由编译器验证的,所以它们可能包含导致创建错误字符串的错误
如
logger.info("删除" + bucketName + "Bucket成功");
解决:字符串输出使用占位符拼接
如
logger.info("删除{}Bucket成功","bucketName");
27."Random" objects should be reused
说明:不要通过创建随机对象的方式获取随机值
解决:创建一个全局对象
28.Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used
说明:线程安全的类 Vector,Hashtable,Stack 和 StringBuffer 不应该被使用
解决:这些类效能低,应当使用ArrayList或LinkedList而不是Vector,Deque代替Stack,HashMap而不是Hashtable,StringBuilder而不是StringBuffer
29.Methods should not have identical implementations
说明:两个方法不应该有相同的实现
解决:删除其中一个方法(注意看影响范围并将删除方法的引用做切换)
30.Methods returns should not be invariant
说明:方法返回不应该是不变的
解决:一般属于结构可优化,后续返回是无用的
31.Collapsible "if" statements should be merged
说明:应该合并无需分层的"if"语句
解决:可合并if判断语句
32.Modifiers should be declared in the correct order
说明:修饰符应该以正确的顺序声明
解决:应该按照如下顺序
Annotations
public
protected
private
abstract
static
final
transient
volatile
synchronized
native
default
strictfp
33.Two branches in a conditional structure should not have exactly the same implementation
说明:(switch 启用 case/if...else if/if...else)条件结构中的两个分支不应该具有完全相同的实现
解决:分支代码块代码一致的情况下应直接合并if判断条件
34.Try-catch blocks should not be nested
说明:不应该嵌套的使用 try-catch 代码块
如:
try {
// 利用jdk中自带的转换类实现
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
// 格式化xml输出的格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
// 将对象转换成输出流形式的xml
// 创建输出流
FileWriter fw = null;
try {
fw = new FileWriter(path);
} catch (IOException e) {
e.printStackTrace();
}
marshaller.marshal(obj, fw);
} catch (JAXBException e) {
e.printStackTrace();
}
解决:将catch中的异常等级排序放入多个
如:
try {
// 利用jdk中自带的转换类实现
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
// 格式化xml输出的格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
// 将对象转换成输出流形式的xml
// 创建输出流
FileWriter fw = null;
fw = new FileWriter(path);
marshaller.marshal(obj, fw);
} catch (IOException e) {
e.printStackTrace();
}catch (JAXBException e) {
e.printStackTrace();
}