通过Sonar的代码质量报告学习【如何写安全高质量的代码】
1.不要用.size(),改用isEmpty()
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
, ParseException
and MalformedURLException
exceptions are arguably used to indicate nonexceptional outcomes. Similarly, dealing with NoSuchMethodException
is 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 exceptions
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.
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 null
to 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
class
andinterface
- comparing unrelated
interface
types - comparing an array to a non-array
- comparing two arrays
Specifically in the case of arrays, since arrays don't override Object.equals()
, calling equals
on two arrays is the same as comparing their addresses. This means that array1.equals(array2)
is equivalent toarray1==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 orArrays.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 case
7.方法入参需要进行赋值操作的时候推荐用新的变量
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 this
was 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' toString
method, it's a waste of memory and cycles because those methods arestatic
, and can therefore be used without a class instance. Similarly, using the static
method valueOf
in the primitive-wrapper classes with a non-String
argument 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 Exception
prevents 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.
- @Override
- public void myMethod() throws Exception {...}
11.indexOf()方法针对字符char操作,不推荐对String操作,所以不能用双引号“”,推荐用单引号''
An indexOf
or lastIndexOf
call with a single letter String
can be made more performant by switching to a call with a char
argument.
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
, Hashtable
and 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:
ArrayList
orLinkedList
instead ofVector
Deque
instead ofStack
HashMap
instead ofHashtable
StringBuilder
instead ofStringBuffer
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.
- @Override
- public 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的代码质量报告学习【如何写安全高质量的代码】的更多相关文章
- 如何写出高质量的技术博客 这边文章出自http://www.jianshu.com/p/ae9ab21a5730 觉得不错直接拿过来了 好东西要大家分享嘛
如何写出高质量的技术博客?答案是:如果你想,就一定能写出高质量的技术博客.看起来很唯心,但这就是事实.有足够愿力去做一件目标明确,有良好反馈系统的事情往往很简单.就是不停地训练,慢慢地,你自己 ...
- 如何写出高质量的JavaScript代码
优秀的Stoyan Stefanov在他的新书中(<Javascript Patterns>)介绍了很多编写高质量代码的技巧,比如避免使用全局变量,使用单一的var关键字,循环式预存长度等 ...
- Mysql写出高质量的sql语句的几点建议
CleverCode在实际的工作也写过一些低效率的sql语句.这些语句会给数据库带来非常大的压力.最基本的表现就是sql语句执行慢,后来逐渐的去优化和尝试. 总结了一些高质量的sql语句的写法.这里C ...
- 如何组织css,写出高质量的css代码
!如何组织css一:css的API 属于基础部分,这部分的能力用“对”和“错”来评判. 比如说把文字设置为红色,只能用color:red:这种写法是对的,其他任何写法都是错的. 二:css框架 不能用 ...
- 如何写出高质量的Python代码--做好优化--改进算法点滴做起
小伙伴你的程序还是停留在糊墙吗?优化代码可以显示程序员的素质欧! 普及一下基础了欧: 一层for简写:y = [1,2,3,4,5,6],[(i*2) for i in y ] 会输出 ...
- 使用firbug调试程序写更高质量的代码设置方法
在搜狐浏览器内输入about:config 在搜索栏中输入:strict 双击javascript.options.strict,将值变为true
- gdb 调试入门,大牛写的高质量指南
引用自:http://blog.jobbole.com/107759/ gdb 调试 ncurses 全过程: 发现网上的“gdb 示例”只有命令而没有对应的输出,我有点不满意.gdb 是 GNU 调 ...
- 如何编写高质量的js代码--底层原理
转自: 如何编写高质量的 JS 函数(1) -- 敲山震虎篇 本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm ...
- 如何编写高质量的C#代码(一)
从"整洁代码"谈起 一千个读者,就有一千个哈姆雷特,代码质量也同样如此. 想必每一个对于代码有追求的开发者,对于"高质量"这个词,或多或少都有自己的一丝理解.当 ...
随机推荐
- HTTP之Cookie
cookie是什么 浏览器存储在本地电脑上的一小段文本文件,cookie的存在主要是为了解决http协议无状态的问题,例如通过cookie来判断用户的登录状态,是否是某一个用户等. cookie的结构 ...
- go get golang.org/x 包失败解决方法
由于墙的原因,国内使用 go get安装golang 官方包可能会失败 解决方法 方法1 [不需要FQ] Win10下相关配置: GOPATH : E:\go 安装记录: E:\>go get ...
- docker logs 查看实时日志
docker logs -f -t --since="2017-05-31" --tail=10 edu_web_1 --since : 此参数指定了输出日志开始日期,即只输出指定 ...
- 廖雪峰Java2面向对象编程-6Java核心类-4JavaBean
1.JavaBean定义 符合以下命名规范的class被成为JavaBean private 类型的field 针对这个field的get和set方法 public class Person { pr ...
- 引用文章 如何在lambda中引入递归调用
// clang++ 3.5 // maybe gcc 4.9 support it, but I don't test it #include<iostream> int main() ...
- 1120 Friend Numbers (20 分)
1120 Friend Numbers (20 分) Two integers are called "friend numbers" if they share the same ...
- synchronous-request-with-websockets
https://stackoverflow.com/questions/13417000/synchronous-request-with-websockets
- mysql命令行批量插入100条数据命令
先介绍一个关键字的使用: delimiter 定好结束符为"$$",(定义的时候需要加上一个空格) 然后最后又定义为";", MYSQL的默认结束符为" ...
- 第11课 std::bind和std::function(2)_std::bind绑定器
1. 温故知新:std::bind1st和std::bind2nd (1)bind1st.bind2nd首先它们都是函数模板,用于将参数绑定到可调用对象(如函数.仿函数等)的第1个或第2个参数上. ( ...
- Delphi根据方法名调用方法
type TForm1 = class(TForm) public published procedure DoJsCall(str:string); ...