Contents
  1. 1. 2019/03/19
  2. 2. 1.用collection.isEmpty()替换collection.size
  3. 3. 2.BigDecimal(double)的问题
  4. 4. 3.String 判断是否相等的问题
  5. 5. 4.if while for switch and try 嵌套不宜过深(尽量不宜超过3层)
  6. 6. 5.不应该直接调用e.printStackTrace(),而是用loggers来处理(就是打log)

2019/03/19

1.用collection.isEmpty()替换collection.size

point:

Collection.isEmpty() should be used to test for emptiness (squid:S1155)

Using Collection.size() to test for emptiness works, but using Collection.isEmpty() makes the code more readable and can be more performant. The time complexity of any isEmpty() method implementation should be O(1) whereas some implementations of size() can be O\(n).

翻译:使用collection.size()测试空性是可行的,但是使用collection.isEmpty()可以使代码更可读,更具性能。任何isEmpty()方法实现的时间复杂性都应该是O(1),而某些size()的实现可以是O(n)。

Noncompliant Code Example

1
2
3
if (myCollection.size() == 0) {  // Noncompliant
/* ... */
}

Compliant Solution

1
2
3
if (myCollection.isEmpty()) {    // Compliant
/* ... */
}

2.BigDecimal(double)的问题

有关于BigDecimal初始化问题请参考 JAVA BigDecimal详解

“BigDecimal(double)” should not be used
级别:bug

Because of floating point imprecision, you’re unlikely to get the value you expect from the BigDecimal(double) constructor.

Instead, you should use BigDecimal.valueOf, which uses a string under the covers to eliminate floating point rounding errors.

Noncompliant Code Example

1
2
3
double d = 1.1;
BigDecimal bd1 = new BigDecimal(d); // Noncompliant; see comment above
BigDecimal bd2 = new BigDecimal(1.1); // Noncompliant; same result

Compliant Solution

1
2
3
double d = 1.1;
BigDecimal bd1 = BigDecimal.valueOf(d);
BigDecimal bd2 = BigDecimal.valueOf(1.1);

不要使用BigDecimal(double)去构造一个BigDecimal对象,因为double类型在计算机表示方法中并不精确,因此,BigDecimal(double)构造出来的对象很可能不是预期的大小,若一定要使用double类型去构造一个BigDecimal对象,请使用BigDecimal.valueOf方法,该方法先将double转换为String,再通过String构造BigDecimal对象,通常更建议使用public BigDecimal(String val)构造方法。

3.String 判断是否相等的问题

Strings literals should be placed on the left side when checking for equality (squid:S1132)

It is preferable to place string literals on the left-hand side of an equals() or equalsIgnoreCase() method call. This prevents null pointer exceptions from being raised, as a string literal can never be null by definition.

翻译: 最好将字符串文本放在equals()或equalSignoreCase()方法调用的左侧。这可以防止引发空指针异常,因为字符串文本不能根据定义为空。

4.if while for switch and try 嵌套不宜过深(尽量不宜超过3层)

Control flow statements “if”, “for”, “while”, “switch” and “try” should not be nested too deeply (squid:S134)

Nested if, for, while, switch, and try statements is a key ingredient for making what’s known as “Spaghetti code”.

Such code is hard to read, refactor and therefore maintain.

Noncompliant Code Example

With the default threshold of 3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (condition1) {                  // Compliant - depth = 1
/* ... */
if (condition2) { // Compliant - depth = 2
/* ... */
for(int i = 0; i < 10; i++) { // Compliant - depth = 3, not exceeding the limit
/* ... */
if (condition4) { // Noncompliant - depth = 4
if (condition5) { // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
/* ... */
}
return;
}
}
}
}

解决方案:参考博客

方法1:接口分层,把接口分为外部和内部接口,所有空值判断放在外部接口完成,只处理一次

方法2:多态,利用多态,每种业务单独处理,在接口不再做任何业务判断。

方法3:使用Map替换分支语句

把所有分享子类型预先缓存在Map里,那么就可以直接get获取具体类型,消除分支

5.不应该直接调用e.printStackTrace(),而是用loggers来处理(就是打log)

log的优势就是用户可以轻松检索日志

#

Throwable.printStackTrace(...) prints a throwable and its stack trace to some stream.

Loggers should be used instead to print throwables, as they have many advantages:

  • Users are able to easily retrieve the logs.
  • The format of log messages is uniform and allow users to browse the logs easily.

The following code:

1
2
3
4
5
try {
/* ... */
} catch(Exception e) {
e.printStackTrace(); // Noncompliant
}

should be refactored into:

1
2
3
4
5
try {
/* ... */
} catch(Exception e) {
LOGGER.log("context", e); // Compliant
}
Contents
  1. 1. 2019/03/19
  2. 2. 1.用collection.isEmpty()替换collection.size
  3. 3. 2.BigDecimal(double)的问题
  4. 4. 3.String 判断是否相等的问题
  5. 5. 4.if while for switch and try 嵌套不宜过深(尽量不宜超过3层)
  6. 6. 5.不应该直接调用e.printStackTrace(),而是用loggers来处理(就是打log)