通过Sonar的代码质量报告学习【如何写安全高质量的代码】
2016-11-17 10:02
495 查看
1.不要用.size(),改用isEmpty()
Using
the code more readable and can be more performant. The time complexity of any
implementation should be
be
2.当catch异常的时候,要么打Log,要么Throw出去,不要什么都不做When handling a caught exception, the original exception's message and stack trace should be logged or passed forward.
try {
myInteger = Integer.parseInt(myString);
} catch (NumberFormatException e) {
// It is perfectly acceptable to not handle "e" here
myInteger = 0;
}
3.已经定义的字符串,不要再使用toString()方法Invoking a method designed to return a string representation of an object which is already a string is a waste of keystrokes. This redundant construction may be optimized by the compiler, but will be confusing in the meantime.
A dead store happens when a local variable is assigned a value, including
Comparisons of dissimilar types will always return false. The comparison and all its dependent code can simply be removed. This includes:comparing an object with null
comparing an object with an unrelated primitive (E.G. a string with an int)
comparing unrelated classes
comparing an unrelated
comparing unrelated
comparing an array to a non-array
comparing two arrays
Specifically in the case of arrays, since arrays don't override
It is preferable to place string literals on the left-hand side of an
While it is technically correct to assign to parameters from within method bodies, it is typically done in error, with the intent to assign a parameter value to a field of the same name, (and
Empty statements, i.e.
There was a typo which lead the semicolon to be doubled, i.e.
"Boxing" is the process of putting a primitive value into a primitive-wrapper object. When that's done purely to use the wrapper class'
Using such generic exceptions as
public void myMethod() throws Exception {...}11.indexOf()方法针对字符char操作,不推荐对String操作,所以不能用双引号“”,推荐用单引号''
An
Early classes of the Java API, such as
public Vector getCats() {...}
Hardcoding an IP address into source code is a bad idea for several reasons:a recompile is required if the address changes
it forces the same address to be used in every environment (dev, sys, qa, prod)
it places the responsibility of setting the value to use in production on the shoulders of the developer
it allows attackers to decompile the code and thereby discover a potentially sensitive address
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).
Noncompliant Code Example
if (myCollection.size() == 0) { // Noncompliant /* ... */ }
Compliant Solution
if (myCollection.isEmpty()) { /* ... */ }
2.当catch异常的时候,要么打Log,要么Throw出去,不要什么都不做When handling a caught exception, the original exception's message and stack trace should be logged or passed forward.
Noncompliant Code Example
// Noncompliant - exception is lost try { /* ... */ } catch (Exception e) { LOGGER.info("context"); } // Noncompliant - exception is lost (only message is preserved) try { /* ... */ } catch (Exception e) { LOGGER.info(e.getMessage()); } // Noncompliant - exception is lost try { /* ... */ } catch (Exception e) { throw new RuntimeException("context"); }
Compliant Solution
try { /* ... */ } catch (Exception e) { LOGGER.info(e); } try { /* ... */ } catch (Exception e) { throw new RuntimeException(e); } try { /* ... */ } catch (RuntimeException e) { doSomething(); throw e; } catch (Exception e) { // Conversion into unchecked exception is also allowed throw new RuntimeException(e); }
Exceptions
InterruptedException,
NumberFormatException,
ParseExceptionand
MalformedURLExceptionexceptions are arguably used to indicate nonexceptional outcomes. Similarly, dealing with
NoSuchMethodExceptionis often required when dealing with the Java reflection API.Because they are part of Java, developers have no choice but to deal with them. This rule does not verify that those particular exceptions are correctly handled.int myInteger;
try {
myInteger = Integer.parseInt(myString);
} catch (NumberFormatException e) {
// It is perfectly acceptable to not handle "e" here
myInteger = 0;
}
See
CERT, ERR00-J. - Do not suppress or ignore checked exceptions3.已经定义的字符串,不要再使用toString()方法Invoking a method designed to return a string representation of an object which is already a string is a waste of keystrokes. This redundant construction may be optimized by the compiler, but will be confusing in the meantime.
Noncompliant Code Example
String message = "hello world"; System.out.println(message.toString()); // Noncompliant;
Compliant Solution
String message = "hello world"; System.out.println(message);4.变量不要初始化为null,不初始化就可以。
A dead store happens when a local variable is assigned a value, including
null, that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources.Even assigning
nullto a variable is a dead store if the variable is not subsequently used. Assigning null as a hint to the garbage collector used to be common practice, but is no longer needed and such code should be eliminated.
Noncompliant Code Example
public void pow(int a, int b) { if(b == 0) { return 0; } int x = a; for(int i= 1, i < b, i++) { x = x * a; //Dead store because the last return statement should return x instead of returning a } return a; }
Compliant Solution
public void pow(int a, int b) { if(b == 0) { return 0; } int x = a; for(int i= 1, i < b, i++) { x = x * a; } return x; }5.equals方法左右两边的数据类型必须保持一致,例如:不能左边是int,右边是String
Comparisons of dissimilar types will always return false. The comparison and all its dependent code can simply be removed. This includes:comparing an object with null
comparing an object with an unrelated primitive (E.G. a string with an int)
comparing unrelated classes
comparing an unrelated
classand
interface
comparing unrelated
interfacetypes
comparing an array to a non-array
comparing two arrays
Specifically in the case of arrays, since arrays don't override
Object.equals(), calling
equalson two arrays is the same as comparing their addresses. This means that
array1.equals(array2)is equivalent to
array1==array2.However, some developers might expect
Array.equals(Object obj)to do more than a simple memory address comparison, comparing for instance the size and content of the two arrays. Instead, the
==operator or
Arrays.equals(array1, array2)should always be used with arrays.
Noncompliant Code Example
interface KitchenTool { ... }; interface Plant {...} public class Spatula implements KitchenTool { ... } public class Tree implements Plant { ...} //... Spatula spatula = new Spatula(); KitchenTool tool = spatula; KitchenTool [] tools = {tool}; Tree tree = new Tree(); Plant plant = tree; Tree [] trees = {tree}; if (spatula.equals(tree)) { // Noncompliant; unrelated classes // ... } else if (spatula.equals(plant)) { // Noncompliant; unrelated class and interface // ... } else if (tool.equals(plant)) { // Noncompliant; unrelated interfaces // ... } else if (tool.equals(tools)) { // Noncompliant; array & non-array // ... } else if (trees.equals(tools)) { // Noncompliant; incompatible arrays // ... } else if (tree.equals(null)) { // Noncompliant // ... }6.equals方法推荐把常量放左边,变量放右边
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.
Noncompliant Code Example
String myString = null; System.out.println("Equal? " + myString.equals("foo")); // Noncompliant; will raise a NPE System.out.println("Equal? " + (myString != null && myString.equals("foo"))); // Noncompliant; null check could be removed
Compliant Solution
System.out.println("Equal?" + "foo".equals(myString)); // properly deals with the null case7.方法入参需要进行赋值操作的时候推荐用新的变量
While it is technically correct to assign to parameters from within method bodies, it is typically done in error, with the intent to assign a parameter value to a field of the same name, (and
thiswas forgotten).If it is done on purpose, a better course would be to use temporary variables to store intermediate results. Allowing parameters to be assigned to also reduces code readability because developers won't be able to tell whether the original parameter or some temporary variable is being accessed without going through the whole method. Moreover, some developers might also expect assignments of method parameters to be visible to callers, which is not the case, and this lack of visibility could confuse them. Instead, all parameters, caught exceptions, and foreach parameters should be treated as
final.
Noncompliant Code Example
class MyClass { public String name; public MyClass(String name) { name = name; // Noncompliant - useless identity assignment } public int add(int a, int b) { a = a + b; // Noncompliant /* additional logic */ return a; // Seems like the parameter is returned as is, what is the point? } public static void main(String[] args) { MyClass foo = new MyClass(); int a = 40; int b = 2; foo.add(a, b); // Variable "a" will still hold 40 after this call } }
Compliant Solution
class MyClass { public String name; public MyClass(String name) { this.name = name; // Compliant } public int add(int a, int b) { return a + b; // Compliant } public static void main(String[] args) { MyClass foo = new MyClass(); int a = 40; int b = 2; foo.add(a, b); } }8.去掉多余的分号
Empty statements, i.e.
;, are usually introduced by mistake, for example because:It was meant to be replaced by an actual statement, but this was forgotten.
There was a typo which lead the semicolon to be doubled, i.e.
;;.
Noncompliant Code Example
void doSomething() { ; // Noncompliant - was used as a kind of TODO marker } void doSomethingElse() { System.out.println("Hello, world!");; // Noncompliant - double ; ... for (int i = 0; i < 3; System.out.println(i), i++); // Noncompliant - Rarely, they are used on purpose as the body of a loop. It is a bad practice to have side-effects outside of the loop body ... }
Compliant Solution
void doSomething() {} void doSomethingElse() { System.out.println("Hello, world!"); ... for (int i = 0; i < 3; i++){ System.out.println(i); } ... }9.不推荐用+"",老老实实用.toString()
"Boxing" is the process of putting a primitive value into a primitive-wrapper object. When that's done purely to use the wrapper class'
toStringmethod, it's a waste of memory and cycles because those methods are
static, and can therefore be used without a class instance. Similarly, using the
staticmethod
valueOfin the primitive-wrapper classes with a non-
Stringargument should be avoided, as should concatenating empty string
""to a primitive.
Noncompliant Code Example
int myInt = 4; String myIntString = new Integer(myInt).toString(); // Noncompliant; creates & discards an Integer object myIntString = Integer.valueOf(myInt).toString(); // Noncompliant myIntString = 4 + ""; // Noncompliant
Compliant Solution
int myInt = 4; String myIntString = Integer.toString(myInt);10.不要随便抛个运行时异常,走点心,用自己定义的异常
Using such generic exceptions as
Error,
RuntimeException,
Throwable, and
Exceptionprevents calling methods from handling true, system-generated exceptions differently than application-generated errors.
Noncompliant Code Example
public void foo(String bar) throws Throwable { // Noncompliant throw new RuntimeException("My Message"); // Noncompliant }
Compliant Solution
public void foo(String bar) { throw new MyOwnRuntimeException("My Message"); }
Exceptions
Generic exceptions in the signatures of overriding methods are ignored.@Overridepublic void myMethod() throws Exception {...}11.indexOf()方法针对字符char操作,不推荐对String操作,所以不能用双引号“”,推荐用单引号''
An
indexOfor
lastIndexOfcall with a single letter
Stringcan be made more performant by switching to a call with a
charargument.
Noncompliant Code Example
String myStr = "Hello World"; // ... int pos = myStr.indexOf("W"); // Noncompliant // ... int otherPos = myStr.lastIndexOf("r"); // Noncompliant // ...
Compliant Solution
String myStr = "Hello World"; // ... int pos = myStr.indexOf('W'); // ... int otherPos = myStr.lastIndexOf('r'); // ...12.StringBuilder大部分情况想比StringBuffer好用,性能高。单线程的时候就用StringBuilder就行了
Early classes of the Java API, such as
Vector,
Hashtableand
StringBuffer, were synchronized to make them thread-safe. Unfortunately, synchronization has a big negative impact on performance, even when using these collections from a single thread.It is better to use their new unsynchronized replacements:
ArrayListor
LinkedListinstead of
Vector
Dequeinstead of
Stack
HashMapinstead of
Hashtable
StringBuilderinstead of
StringBuffer
Noncompliant Code Example
Vector cats = new Vector();
Compliant Solution
ArrayList cats = new ArrayList();
Exceptions
Use of those synchronized classes is ignored in the signatures of overriding methods.@Overridepublic Vector getCats() {...}
13.cookie必须setSercure(true)The "secure" attribute prevents cookies from being sent over plaintext connections such as HTTP, where they would be easily eavesdropped upon. Instead, cookies with the secure attribute are only sent over encrypted HTTPS connections.
Noncompliant Code Example
Cookie c = new Cookie(SECRET, secret); // Noncompliant; cookie is not secure response.addCookie(c);
Compliant Solution
Cookie c = new Cookie(SECRET, secret); c.setSecure(true); response.addCookie(c);14.推荐把内容复杂的常量变得可配置化,就是将它放在常量类里进行统一管理,或者环境变量
Hardcoding an IP address into source code is a bad idea for several reasons:a recompile is required if the address changes
it forces the same address to be used in every environment (dev, sys, qa, prod)
it places the responsibility of setting the value to use in production on the shoulders of the developer
it allows attackers to decompile the code and thereby discover a potentially sensitive address
Noncompliant Code Example
String ip = "127.0.0.1"; Socket socket = new Socket(ip, 6667);
Compliant Solution
String ip = System.getProperty("myapplication.ip"); Socket socket = new Socket(ip, 6667);
See
CERT, MSC03-J. - Never hard code sensitive information相关文章推荐
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 通过Sonar的代码质量报告学习【如何写安全高质量的代码】
- 如何通过代码加密对服务器安全进行保护?