误导性缩进¶
ID: java/misleading-indentation
Kind: problem
Security severity:
Severity: warning
Precision: very-high
Tags:
- maintainability
- correctness
- logic
Query suites:
- java-security-and-quality.qls
控制结构(if
语句或循环)的主体是带有大括号的语句块或单个语句。
如果您省略大括号,确保代码的缩进与代码的控制流匹配尤为重要。
建议¶
通常认为,为 Java 中的所有控制结构添加大括号是一种好习惯。这是因为它使以后维护代码变得更容易。例如,您可以一目了然地看出代码的哪一部分在 if
语句的范围内,并且向 if
语句的主体添加更多语句不太容易出错。
您还应确保代码的缩进与实际控制流一致,这样才不会让程序员感到困惑。
示例¶
在下面的示例中,Cart
的原始版本缺少大括号。这意味着如果 i
为 null
,则代码会在运行时触发 NullPointerException
。
class Cart {
Map<Integer, Integer> items = ...
public void addItem(Item i) {
// No braces and misleading indentation.
if (i != null)
log("Adding item: " + i);
// Indentation suggests that the following statements
// are in the body of the 'if'.
Integer curQuantity = items.get(i.getID());
if (curQuantity == null) curQuantity = 0;
items.put(i.getID(), curQuantity+1);
}
}
Cart
的更正版本确实包含大括号,以便代码按缩进建议执行。
class Cart {
Map<Integer, Integer> items = ...
public void addItem(Item i) {
// Braces included.
if (i != null) {
log("Adding item: " + i);
Integer curQuantity = items.get(i.getID());
if (curQuantity == null) curQuantity = 0;
items.put(i.getID(), curQuantity+1);
}
}
}
在以下示例中,缩进可能会或可能不会误导,具体取决于您的制表符宽度设置。因此,不建议以这种方式混合制表符和空格,因为在一个上下文中看起来很正常的东西在另一个上下文中可能会非常具有误导性。
// Tab width 8
if (b) // Indentation: 1 tab
f(); // Indentation: 2 tabs
g(); // Indentation: 8 spaces
// Tab width 4
if (b) // Indentation: 1 tab
f(); // Indentation: 2 tabs
g(); // Indentation: 8 spaces
如果您以这种方式混合制表符和空格,那么您可能会得到看似错误的正例,因为无法考虑您的制表符宽度设置。