SonarQube Java 规则描述

文章目录

  • 阻断
  • 严重
  • 主要
  • 次要

阻断

1、“PreparedStatement” and “ResultSet” methods should be called with valid indices
PreparedStatement 与 ResultSet 参数设置与获取数据由序号 1 开始而非 0。

PreparedStatement ps = con.prepareStatement("SELECT fname, lname FROM employees where hireDate > ? and salary < ?");
ps.setDate(0, date);  // Noncompliant
ps.setDouble(3, salary);  // Noncompliant

ResultSet rs = ps.executeQuery();
while (rs.next()) {
    String fname = rs.getString(0);  // Noncompliant
  // ...
}

2、 “wait” should not be called when multiple locks are held
wait() 方法不应该在多重锁内被使用,此时线程只释放了内层锁,而没有释放外层锁,可能导致死锁。

synchronized (this.mon1) {  // threadB can't enter this block to request this.mon2 lock & release threadA
    synchronized (this.mon2) {
		this.mon2.wait();  // Noncompliant; threadA is stuck here holding lock on this.mon1
	}
}

3、“wait(…)” should be used instead of “Thread.sleep(…)” when a lock is held
当持有锁的当前线程调用 Thread.sleep (…) 时,可能导致死锁问题。因为被挂起的线程一直持有锁。合适的做法是调用锁对象的 wait () 释放锁让其它等待线程运行。

public void doSomething(){
  synchronized(monitor) {
    while(notReady()){
      Thread.sleep(200);
    }
    process();
  }
  ...
}

应:

public void doSomething(){
  synchronized(monitor) {
    while(notReady()){
      monitor.wait(200);
    }
    process();
  }
  ...
}

4、Double-checked locking should not be used
单例懒汉模式:当变量没加 volatile 修饰时,不要使用双重检查

public class DoubleCheckedLocking {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null) {
            synchronized (DoubleCheckedLocking.class) {
                if (resource == null)
                    resource = new Resource();
            }
        }
        return resource;
    }

    static class Resource {

    }
}

public class SafeLazyInitialization {
    private static Resource resource;

    public synchronized static Resource getInstance() {
        if (resource == null)
            resource = new Resource();
        return resource;
    }

    static class Resource {
    }
}

5、Loops should not be infinit
不应该存在死循环。

int j;
while (true) { // Noncompliant; end condition omitted
    j++;
}

6、Methods “wait(…)”, “notify()” and “notifyAll()” should not be called on Thread instances
不应该调用线程实例的 “wait (…)”, “notify ()” and “notifyAll ()”。

Thread myThread = new Thread(new RunnableJob());
...
myThread.wait(2000);

7、Printf-style format strings should not lead to unexpected behavior at runtime
因为 Printf 风格格式化是在运行期解读,而不是在编译期检验,所以会存在风险。

String.format("Not enough arguments %d and %d", 1);  //Noncompliant; the second argument is missing
String.format("The value of my integer is %d", "Hello World");  // Noncompliant; an 'int' is expected rather than a String
String.format("Duke's Birthday year is %tX", c);  //Noncompliant; X is not a supported time conversion character
String.format("Display %0$d and then %d", 1);   //Noncompliant; arguments are numbered starting from 1
String.format("%< is equals to %d", 2);   //Noncompliant; the argument index '<' refers to the previous format specifier but there isn't one

8、Resources should be closed
打开的资源应该关闭并且放到 finally 块中进行关闭。可以使用 JDK7 的 try-with-resources 表达式

private void readTheFile() throws IOException {
  Path path = Paths.get(this.fileName);
  BufferedReader reader = Files.newBufferedReader(path, this.charset);
  // ...
  reader.close();  // Noncompliant
  // ...
  Files.lines("input.txt").forEach(System.out::println); // Noncompliant: The stream needs to be closed
}

private void doSomething() {
  OutputStream stream = null;
  try {
    for (String property : propertyList) {
      stream = new FileOutputStream("myfile.txt");  // Noncompliant
      // ...
    }
  } catch (Exception e) {
    // ...
  } finally {
    stream.close();  // Multiple streams were opened. Only the last is closed.
  }
}

严重

标记1、“runFinalizersOnExit” should not be called
默认情况 JVM 退出时是不运行 finalizers 的,System.runFinalizersOnExit 和 Runtime.runFinalizersOnExit 可以在 jvm 退出时运行,但是因为他们不安全而弃用。

public static void main(String [] args) {
  ...
  System.runFinalizersOnExit(true);  // Noncompliant
}

protected void finalize(){
  doSomething();
}

应:

        Runtime.addShutdownHook(new Runnable() {
            public void run(){
                doSomething();
            }
        });

2、“ScheduledThreadPoolExecutor” should not have 0 core threads
java.util.concurrent.ScheduledThreadPoolExecutor 由 corePoolSize 指定核心线程数,如果设置为 0 表示线程池无线程可用且不做任何事。
在这里插入图片描述
在这里插入图片描述

3、 “super.finalize()” should be called at the end of “Object.finalize()” implementations

        protected void finalize() {
            releaseSomeResources();
            super.finalize (); // 调用,最后调用
        }

4、Dependencies should not have “system” scope
maven 依赖不应该有 system 类型的依赖范围,使得系统的可移植性低。

<dependency>
  <groupId>javax.sqlgroupId>
  <artifactId>jdbc-stdextartifactId>
  <version>2.0version>
  <scope>systemscope>  
  <systemPath>/usr/bin/lib/rt.jarsystemPath>  
dependency>

5、Locks should be released
保证锁能够被释放

public class MyClass {
  private Lock lock = new Lock();

  public void doSomething() {
    lock.lock(); // Noncompliant
    if (isInitialized()) {
      // ...
      lock.unlock();
    }
  }
}

应:

public class MyClass {
  private Lock lock = new Lock();

  public void doSomething() {
    if (isInitialized()) {
      lock.lock();
      // ...
      lock.unlock();
    }
  }
}

标记6、The signature of “finalize()” should match that of "Object.finalize()"
普通方法不应该以 finalize 命名。以免和 Object.finalize() 方法混淆。

public int finalize(int someParameter) {        // Noncompliant
  /* ... */
}

应:

public int someBetterName(int someParameter) {  // Compliant
  /* ... */
}

7、Zero should not be a possible denominator
分母不应该为零

void test_divide() {
  int z = 0;
  if (unknown()) {
    // ..
    z = 3;
  } else {
    // ..
  }
  z = 1 / z; // Noncompliant, possible division by zero
}

主要

标记1、".equals()" should not be used to test the values of “Atomic” classes
不要使用 equals 方法对 AtomicXXX 进行是否相等的判断
Atomic 变量是设计来无锁解决原子性问题的,逻辑上他永远只会和自身相等,Atomic 变量没有重写 equals () 方法。
SonarQube Java 规则描述_第1张图片

2、"=+" should not be used instead of "+="
“=+” 与 “+=” 意义不同
a =+ b; 虽然正确但写法不合规,应写成 a = +b。

int target = -5;
int num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

应:

int target = -5;
int num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;

标记3、“BigDecimal(double)” should not be used
因为浮点的不精确,使用 BigDecimal (double) 可能得不到期望的值。
推荐:浮点精度运算不精确的原因

double d = 1.1;

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

应:

double d = 1.1;

BigDecimal bd1 = BigDecimal.valueOf(d);
BigDecimal bd2 = new BigDecimal("1.1"); // using String constructor will result in precise value

4、 “Double.longBitsToDouble” should not be used for "int"
Double.longBitsToDouble 返回给定的位所代表的 double 值,需要一个 64 位的 long 类型参数。

int i = 42;
double d = Double.longBitsToDouble(i);  // Noncompliant

5、“equals” method overrides should accept “Object” parameters
equals 作为方法名应该仅用于重写 Object.equals (Object) 来避免混淆。

class MyClass {
  private int foo = 1;

  public boolean equals(MyClass o) {  // Noncompliant; does not override Object.equals(Object)
    return o != null && o.foo == this.foo;
  }

  public static void main(String[] args) {
    MyClass o1 = new MyClass();
    Object o2 = new MyClass();
    System.out.println(o1.equals(o2));  // Prints "false" because o2 an Object not a MyClass
  }
}

class MyClass2 {
  public boolean equals(MyClass2 o) {  // Ignored; `boolean equals(Object)` also present
    //..
  }

  public boolean equals(Object o) {
    //...
  }
}

应:

class MyClass {
  private int foo = 1;

  @Override
  public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    MyClass other = (MyClass)o;
    return this.foo == other.foo;
  }

  /* ... */
}

class MyClass2 {
  public boolean equals(MyClass2 o) {
    //..
  }

  public boolean equals(Object o) {
    //...
  }
}

6、“Externalizable” classes should have no-arguments constructors
Externalizable (可序列化与反序列化) 类应该有无参构造器。
Externalizable 类是处理其自己的序列化和反序列化的类。在反序列化期间,过程的第一步是使用类的无参数构造函数的默认实例化。因此,没有 no-arg 构造函数的 Externalizable 类不能反序列化

public class Tomato implements Externalizable {  // Noncompliant; no no-arg constructor

  public Tomato (String color, int weight) { ... }
}

应:

public class Tomato implements Externalizable {

  public Tomato() { ... }
  public Tomato (String color, int weight) { ... }
}

7、“getClass” should not be used for synchronization
因为 this.getClass() 是以对象作为锁,所以该代码块仍然允许多个线程共同访问。

{
   synchronized (this.getClass())
} 错误 子类继承此方法时不能做到同步
 
{
   synchronized (MyClass.class)
} 正确

8、“hashCode” and “toString” should not be called on array instances
String[] args;
args 属于 Object 类型,调用 str.toString() 方法相当于调用 Object.toString() 方法。
使用 Arrays.toString (args) 和 Arrays.hashCode (args) 代替 args.toString() 和 args.hashCode()。

String argStr = args.toString(); // Noncompliant
int argHash = args.hashCode(); // Noncompliant

9、“InterruptedException” should not be ignored
抛出 InterruptedException 后,会取消 Thread 的中断状态,所以在未正确处理该异常的前提下,可以通过调用 Thread.interrupt() 重新中断线程。

public void run () {
  try {
    while (true) {
      // do stuff
    }
  }catch (InterruptedException e) { // Noncompliant; logging is not enough
    LOGGER.log(Level.WARN, "Interrupted!", e);
  }
}

应:

try {
    while (true) {
		// do stuff
    }
}catch (InterruptedException e) {
    LOGGER.log(Level.WARN, "Interrupted!", e);
		// Restore interrupted state...
    Thread.currentThread().interrupt();
}

10、“Iterator.hasNext()” should not call "Iterator.next()"
错误用法:

        public class FibonacciIterator implements Iterator<Integer>{
...
            @Override
            public boolean hasNext() {
                if(next() != null) {
                    return true;
                }
                return false;
            }
...
        }

标记11、“notifyAll” should be used
notify 可能不能唤醒正确的线程,notifyAll 代之。

12、“null” should not be used with "Optional"
在使用 Optional 封装对象时,永远不会存在从调用返回或接收 null 的问题。

public void doSomething () {
  Optional<String> optional = getOptional();
  if (optional != null) {  // Noncompliant
    // do something with optional...
  }
}

@Nullable // Noncompliant
public Optional<String> getOptional() {
  // ...
  return null;  // Noncompliant
}

应:

public void doSomething () {
  Optional<String> optional = getOptional();
  optional.ifPresent(
    // do something with optional...
  );
}

public Optional<String> getOptional() {
  // ...
  return Optional.empty();
}

13、“read” and “readLine” return values should be used
从某些数据源读取的数据的方法时,应存储该数据而不是将其丢弃,任何其他措施肯定是一个错误。

public void doSomethingWithFile(String fileName) {
  BufferedReader buffReader = null;
  try {
    buffReader = new BufferedReader(new FileReader(fileName));
    while (buffReader.readLine() != null) { // Noncompliant
      // ...
    }
  } catch (IOException e) {
    // ...
  }
}

public void doSomethingWithFile(String fileName) {
  BufferedReader buffReader = null;
  try {
    buffReader = new BufferedReader(new FileReader(fileName));
    String line = null;
    while ((line = buffReader.readLine()) != null) {
      // ...
    }
  } catch (IOException e) {
    // ...
  }
}

14、“SingleConnectionFactory” instances should be set to "reconnectOnException"
使用 Spring SingleConnectionFactory 而不启用 reconnectOnException 设置当连接恶化将阻止自动连接恢复。

 <bean id="singleCF" class="org.springframework.jms.connection.SingleConnectionFactory">  
   <constructor-arg ref="dummyConnectionFactory" />
 bean>

 <bean id="singleCF" class="org.springframework.jms.connection.SingleConnectionFactory" p:reconnectOnException="true">
   <constructor-arg ref="dummyConnectionFactory" />
 bean>

15、“StringBuilder” and “StringBuffer” should not be instantiated with a character
初始化 StringBuilder/StringBuffer 时,如果传入单字符,那么单字符会被识别为其 ASCII 码对应的数字大小。

StringBuffer foo = new StringBuffer ('x'); //错 equivalent to StringBuffer foo = new StringBuffer (120);
StringBuffer foo = new StringBuffer ("x"); //对

在这里插入图片描述
16、“toString()” and “clone()” methods should not return null
可返回 “”

在对象上调用 toString() 或 clone() 应该始终返回字符串或对象。相反,返回null会违反该方法的隐式协定。

17、 “wait”, “notify” and “notifyAll” should only be called when a lock is obviously held on an object
先要获得对象锁才能进行上述操作

private void removeElement() {
  while (!suitableCondition()){
    obj.wait();
  }
  ... // Perform removal
}
or

private void removeElement() {
  while (!suitableCondition()){
    wait();
  }
  ... // Perform removal
}

应:

private void removeElement() {
  synchronized(obj) {
    while (!suitableCondition()){
      obj.wait();
    }
    ... // Perform removal
  }
}
or

private synchronized void removeElement() {
  while (!suitableCondition()){
    wait();
  }
  ... // Perform removal
}

18、A “for” loop update clause should move the counter in the right direction
检查 for 循环下标递增或递减正确

public void doSomething(String [] strings) {
  for (int i = 0; i < strings.length; i--) { // Noncompliant;
    String string = strings[i];  // ArrayIndexOutOfBoundsException when i reaches -1
    //...
  }

19、All branches in a conditional structure should not have exactly the same implementation
程序分支中不应该有相同的实现

switch (i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

20、Blocks should be synchronized on “private final” fields or parameters
synchronized 同步块应该锁在 private final 属性或参数上,因为同步块内非 final 类型的锁对象可能会出现引用改变。

private String color = "red";

private void doSomething(){
  synchronized(color) {  // Noncompliant; lock is actually on object instance "red" referred to by the color variable
    //...
    color = "green"; // other threads now allowed into this block
    // ...
  }
  synchronized(new Object()) { // Noncompliant this is a no-op.
     // ...
  }
}

应:

private String color = "red";
private final Object lockObj = new Object();

private void doSomething(){
  synchronized(lockObj) {
    //...
    color = "green";
    // ...
  }
}

21、Child class methods named for parent class methods should be overrides
子类的方法名是父类方法名时,子类方法应该是重写了父类方法。

以下情况不是重写:
a、父类方法是 static 的而子类方法不是 static 的
b、子类方法的参数或返回值与父类方法不是同一个包
c、父类方法是 private
为了不产生混乱,不要与父类方法同名

22、Classes extending java.lang.Thread should override the “run” method
线程类应该重写 run 方法

public class MyRunner extends Thread { // Noncompliant; run method not overridden

  public void doSometing() {...}
}

Exceptions:

class MyThread extends Thread { // Compliant - calling super constructor with a Runnable
  MyThread(Runnable target) {
    super(target); // calling super constructor with a Runnable, which will be used for when Thread.run() is executed
    // ...
  }
}

23、Classes should not be compared by name
不要用类名称比较类是否相同,而用 instanceof 或者 Class.isAssignableFrom () 进行基础类型比较

if ("Pear".equals(item.getClass().getSimpleName())) {  // Noncompliant
    return true;  // Results in throwing away week-old computers
}
    return false;

24、Collection sizes and array length comparisons should make sense
集合大小和数组长度比较应该有意义。
集合的大小和数组的长度始终大于或等于零。因此,测试大小或长度大于或等于零是没有意义的,因为结果始终为真。类似地,测试它小于零将始终返回false。可能的目的是检查集合或数组的非空性。

if (myList.size() >= 0) { ... }

if (myList.size() < 0) { ... }

boolean result = myArray.length >= 0;

if (0 > myArray.length) { ... }

应:

if (!myList.isEmpty()) { ... }

if (myArray.length >= 42) { ... }

25、Collections should not be passed as arguments to their own methods
集合实例不应该作为参数被传给集合自已的方法
1.要么是代码错误
2.要么仅仅是无意义的代码
3.由于某些方法要求参数在执行期间保持不变,因此将集合传递给自身可能导致未知的异常。

List <Object> objs = new ArrayList<Object>();
objs.add("Hello");

objs.add(objs); // Noncompliant; StackOverflowException if objs.hashCode() called
objs.addAll(objs); // Noncompliant; behavior undefined
objs.containsAll(objs); // Noncompliant; always true
objs.removeAll(objs); // Noncompliant; confusing. Use clear() instead
objs.retainAll(objs); // Noncompliant; NOOP

26、Conditionally executed blocks should be reachable
条件执行块应该有可达性

a = false;
if (a) { // Noncompliant
  doSomething(); // never executed
}

if (!a || b) { // Noncompliant; "!a" is always "true", "b" is never evaluated
  doSomething();
} else {
  doSomethingElse(); // never executed

27、Consumed Stream pipelines should not be reused
流不应该重用
流操作分为中间操作和终端操作,并合并以形成流管道。执行终端操作后,流管道被视为已消耗,无法再次使用。这样的重用将产生意想不到的结果。

Stream<Widget> pipeline = widgets.stream().filter(b -> b.getColor() == RED);
int sum1 = pipeline.sum();
int sum2 = pipeline.mapToInt(b -> b.getWeight()).sum(); // Noncompliant

28、Custom serialization method signatures should meet requirements
自定义类序列化方法名称应该符合要求

public class Watermelon implements Serializable {
  // ...
  void writeObject(java.io.ObjectOutputStream out)// Noncompliant; not private
        throws IOException
  {...}
  public void readObjectNoData()  // Noncompliant; not private
  {...}
}

29、Dissimilar primitive wrappers should not be used with the ternary operator without explicit casting
不同的原始包装类如果没有明确的类转换不能用于三元操作中

Integer i = 123456789;
Float f = 1.0f;
// 如果 condition 为真,将 i 赋值给 n,会导致类型转换异常。
Number n = condition ? i : f;

30、Exception should not be created without being thrown
不被抛出的异常不要创建

if (x < 0)
  new IllegalArgumentException("x must be nonnegative");

应:

if (x < 0)
  throw new IllegalArgumentException("x must be nonnegative");

31、Expressions used in “assert” should not produce side effects
assert 表达式不要出现有效的逻辑表达式,即不要改变数据状态
由于assert语句默认情况下不执行(必须使用 JVM 标志启用),因此我们不应依赖其执行。
Idea 开启断言:
在这里插入图片描述

assert myList.remove(myList.get(0));  // Noncompliant

应:

boolean removed = myList.remove(myList.get(0));
assert removed;

32、Getters and setters should be synchronized in pairs
get 与 set 应该成对进行同步操作,即在 get 中加锁,那么 set 中也应该加锁。

public class Person {
  String name;

  public synchronized void setName(String name) {
    this.name = name;
  }

  public String getName() {  // Noncompliant
    return this.name;
  }
}

应:

public class Person {
  String name;

  public synchronized void setName(String name) {
    this.name = name;
  }

  public synchronized String getName() {
    return this.name;
  }
}

33、Identical expressions should not be used on both sides of a binary operator
相同的表达式不要作为二元操作的操作数使用,应该简化

if ( a != a ) { // always false
  doY();
}
int j = 5 / 5; //always 1

Exceptions:

int i = 1 << 1; // Compliant

34、Inappropriate “Collection” calls should not be made
正确使用集合类型的方法

List<String> list = new ArrayList<String>();
Integer integer = Integer.valueOf(1);

if (list.contains(integer)) {  // Noncompliant. Always false.
  list.remove(integer); // Noncompliant. list.add(integer) doesn't compile, so this will always return false
}

标记35、Inappropriate regular expressions should not be used
正确使用正则表达式

String str = "/File|Name.txt";

String clean = str.replaceAll(".",""); // Noncompliant; probably meant to remove only dot chars, but returns an empty string
String clean2 = str.replaceAll("|","_"); // Noncompliant; yields _/_F_i_l_e_|_N_a_m_e_._t_x_t_
String clean3 = str.replaceAll(File.separator,""); // Noncompliant; exception on Windows

标记36、Intermediate Stream methods should not be left unused
中间流应该被使用

widgets.stream().filter(b -> b.getColor() == RED); // Noncompliant

应:

int sum = widgets.stream()
                      .filter(b -> b.getColor() == RED)
                      .mapToInt(b -> b.getWeight())
                      .sum();
Stream<Widget> pipeline = widgets.stream()
                                 .filter(b -> b.getColor() == GREEN)
                                 .mapToInt(b -> b.getWeight());
sum = pipeline.sum();

37、Invalid “Date” values should not be used
正确使用日期
SonarQube Java 规则描述_第2张图片

Date d = new Date();
d.setDate(25);
d.setYear(2014);
d.setMonth(12);  // Noncompliant; rolls d into the next year

Calendar c = new GregorianCalendar(2014, 12, 25);  // Noncompliant
if (c.get(Calendar.MONTH) == 12) {  // Noncompliant; invalid comparison
  // ...
}

38、Jump statements should not occur in “finally” blocks
finally 块中使用 return, break, throw 等跳转表达式,会阻止在 try catch 中抛出的未处理异常的传播

public static void main(String[] args) {
  try {
    doSomethingWhichThrowsException();
    System.out.println("OK");   // incorrect "OK" message is printed
  } catch (RuntimeException e) {
    System.out.println("ERROR");  // this message is not shown
  }
}

public static void doSomethingWhichThrowsException() {
  try {
    throw new RuntimeException();
  } finally {
    for (int i = 0; i < 10; i ++) {
      //...
      if (q == i) {
        break; // ignored
      }
    }

    /* ... */
    return;      // Noncompliant - prevents the RuntimeException from being propagated
  }
}

39、Loop conditions should be true at least once
循环至少应该走一次

40、Methods should not be named “hashcode” or "equal"
不要使用 hashcode、equal 作为方法名,可能会和 hashCode、equals 出现混淆,导致可读性差。

标记41、Non-public methods should not be "@Transactional"
非 public 方法不要注解 Transactional, 否则可能导致运行时异常

42、Non-serializable classes should not be written
不要忘记实现序列化接口。执行写操作的类要序列化,否则会抛出异常

43、Non-serializable objects should not be stored in “HttpSession” objects
HttpSession 要保存可序列化的对象

public class Address {
  //...
}

//...
HttpSession session = request.getSession();
session.setAttribute("address", new Address());  // Noncompliant; Address isn't serializable

44、Non-thread-safe fields should not be static
非线程安全的属性不应该静态化,静态化会导致所有类对象共享该变量,更容易导致线程安全问题。

public class MyClass {
  static private SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");  // Noncompliant
  static private Calendar calendar = Calendar.getInstance();  // Noncompliant
}

45、Null pointers should not be dereferenced
空指针引用不应被直接访问,要增加判空检验

@CheckForNull
String getName(){...}

public boolean isNameEmpty() {
  return getName().length() == 0; // Noncompliant; the result of getName() could be null, but isn't null-checked
}

46、Optional value should only be accessed after calling isPresent()
Optional 实例值的获取要 isPresent() 之后再做操作:Optional.get() 存在一个值,则返回该值,否则抛出 NoSuchElementException

Optional<String> value = this.getOptionalValue();
// ...
String stringValue = value.get(); // Noncompliant

应:

Optional<String> value = this.getOptionalValue();
// ...
if (value.isPresent()) {
  String stringValue = value.get();
}

or

Optional<String> value = this.getOptionalValue();
// ...
String stringValue = value.orElse("default");

标记47、Raw byte values should not be used in bitwise operations in combination with shifts
原始字节值不应参与位运算

result = (result << 8) | readByte(); // Noncompliant

应:

result = (result << 8) | (readByte() & 0xff);

标记48、Reflection should not be used to check non-runtime annotations
反射操作不应该用于检查非运行时注解

Method m = String.class.getMethod("getBytes", new Class[] {int.class,
int.class, byte[].class, int.class});
if (m.isAnnotationPresent(Override.class)) {  // Noncompliant; test will always return false, even when @Override is present in the code

即使代码中存在@Override,测试也会始终返回false

49、Related “if/else if” statements should not have the same condition
if/else if 中不应该有相同的条件

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 1)  // Noncompliant
  moveWindowToTheBackground();
}

50、Return values from functions without side effects should not be ignored
函数返回值没有起作用的应该被遗弃

public void handle(String command){
    command.toLowerCase(); // Noncompliant; result of method thrown away
    ...
}

51、Silly equality checks should not be made
不好的相等检查不应该做,比如非同类型对象的 equal

Spatula spatula = new Spatula();
if (spatula.equals(tree)) { // Noncompliant; unrelated classes
  // ...
}

标记52、Synchronization should not be based on Strings or boxed primitives
字符串和封箱类不应该被用作锁定对象,因为它们可能被池化或重用。

private static final String sLock = "LOCK";

public void doSomething() {
  synchronized(sLock) {  // Noncompliant
    // ...
  }
}

应:

private static final Object lock3 = new Object();

public void doSomething() {
  synchronized(lock) {
    // ...
  }
}

标记53、The Object.finalize() method should not be called
Object.finalize() 不要人为去调用
根据官方 javadoc 文档,当垃圾回收确定不再有对该对象的引用时,垃圾回收器将在对象上调用此Object.finaliz() 。显式调用此方法会破坏此协议,从而产生误导。

public void dispose() throws Throwable {
  this.finalize();                       // Noncompliant
}

54、Thread.run() should not be called directly
run() 不应该直接被调用,调用 start ()。

Thread myThread = new Thread(runnable);
myThread.run(); // Noncompliant

应:

Thread myThread = new Thread(runnable);
myThread.start(); // Compliant

标记55、Value-based classes should not be used for locking
基于值的类不要用于锁对象

Optional<Foo> fOpt = doSomething();
synchronized (fOpt) {  // Noncompliant
  // ...
}

56、Values should not be uselessly incremented
值增减后不存储是代码浪费甚至是 bug
推荐:局部变量表和操作数栈之间的操作关系

public int pickNumber() {
  int i = 0;
  int j = 0;

  i = i++; // Noncompliant; i is still zero

  return j++; // Noncompliant; 0 returned
}

57、Variables should not be self-assigned
变量不应该出现自分配,如下:

public void setName(String name) {
   name = name;
}

58、Week Year (“YYYY”) should not be used for date formatting
日期格式化错误

Date date = new SimpleDateFormat("yyyy/MM/dd").parse("2015/12/31");
String result = new SimpleDateFormat("YYYY/MM/dd").format(date);   //Noncompliant; yields '2016/12/31'

应:

Date date = new SimpleDateFormat("yyyy/MM/dd").parse("2015/12/31");
String result = new SimpleDateFormat("yyyy/MM/dd").format(date);   //Yields '2015/12/31' as expected

次要

1、"@NonNull" values should not be set to null
被标注非空的字段,不应该被设置为空

2、“compareTo” results should not be checked for specific values
被重写后的 compareTo 方法可能返回不是具体的值(除 0 外),建议用 >0、<0、=0

compareTo () 方法:
如果这个字符串是等参数字符串那么返回值 0,如果这个字符串是按字典顺序小于字符串参数那么返回小于 0 的值,如果此字符串是按字典顺序大于字符串参数那么返回一个大于 0 的值

3、“compareTo” should not return "Integer.MIN_VALUE"
compareTo 只代表一个不等标识,不代表不等的程度,应返回 - 1,0,1 标识即可

public int compareTo(MyClass) {
  if (condition) {
    return Integer.MIN_VALUE;  // Noncompliant
  }

4、 “equals(Object obj)” should test argument type
要比较 obj 的类型是否一样

public boolean equals(Object obj) {
  MyClass mc = (MyClass)obj;  // Noncompliant
  // ...
}

应:

public boolean equals(Object obj) {
  if (obj == null)
    return false;

  if (this.getClass() != obj.getClass())
    return false;

  MyClass mc = (MyClass)obj;
  // ...
}

5、“Iterator.next()” methods should throw "NoSuchElementException"

        public String next(){
            if(!hasNext()){
                throw new NoSuchElementException();
            }
			...
        }

6、“Serializable” inner classes of non-serializable classes should be "static"
序列化非静态内部类将导致尝试序列化外部类,如果外部类不是序列化类,会产生运行时异常,内部类静态化会避免这种情况

7、“toArray” should be passed an array of the proper type
toArray () 无参且强制类型转换会产生运行时异常,应传入一个合适的类弄作参数

public String [] getStringArray(List<String> strings) {
  return (String []) strings.toArray();  // Noncompliant; ClassCastException thrown
}

应:

public String [] getStringArray(List<String> strings) {
  return strings.toArray(new String[0]);
}

ArrayList 的两个 toArray 方法
在这里插入图片描述

8、Boxing and unboxing should not be immediately reversed
自动拆箱和装箱不需显示转换,依托于语法糖即可

标记9、Double Brace Initialization should not be used
双括号初始化不要用

Map source = new HashMap(){{ // Noncompliant
put("firstName", "John");
put("lastName", "Smith");
}};

此操作如一个 anonymous inner class,如果 anonymous inner class 返回且被其它对象引用,可能产生 memory leaks,既使不产生 memory leaks 也会让大多维护者感到迷惑

10、Ints and longs should not be shifted by zero or more than their number of bits-1
整型与长整型位移操作数应该价于 1 与类型占位数 - 1

11、Math operands should be cast before assignment
数字操作在操作或赋值前要转化

12、Neither “Math.abs” nor negation should be used on numbers that could be "MIN_VALUE"
如果对数值类型的 MIN_VALUE 值进行 Math.abs 与取反操作,得到的仍然是一个负值,而由于逻辑上我们已经认为获得了一个正数,从而导致出错。

标记13、The non-serializable super class of a “Serializable” class should have a no-argument constructor
序列化的类的非序列化父类应有一个无参构造器

14、The value returned from a stream read should be checked
从流中读取的值应先检查再操作

public void doSomething(String fileName) {
  try {
    InputStream is = new InputStream(file);
    byte [] buffer = new byte[1000];
    is.read(buffer);  // Noncompliant
    // ...
  } catch (IOException e) { ... }
}

应:

public void doSomething(String fileName) {
  try {
    InputStream is = new InputStream(file);
    byte [] buffer = new byte[1000];
    int count = 0;
    while (count = is.read(buffer) > 0) {
      // ...
    }
  } catch (IOException e) { ... }
}

标记15、Value-based objects should not be serialized
基于值的对象不应被用于序列化

你可能感兴趣的:(笔记,SonarQube,Java,规则)