Sonar規范掃描Java代碼暴露的問題


字符串和封裝類型應使用 equals()進行比較

例如java.lang.Integer使用引用等於==!=,因為它不是比較實際值,而是比較內存中的位置。

String firstName = getFirstName(); // String overrides equals
String lastName = getLastName();

if (firstName == lastName) { ... }; // 即使字符串具有相同的值,也為false


方法參數,捕獲的異常和foreach變量的初始值不應忽略

public void doTheThing(String str, int i, List<String> strings) {
 // str = Integer.toString(i); // 不符合規定
    
  String str1 = str	//在使用之前需要保存初始值
      
  for (String s : strings) {
    s = "hello world"; // Noncompliant
  }
}

"InterruptedException" should not be ignored

在代碼中不應該忽略中斷異常,只在日志中打印異常日志,就像“忽略”一樣。拋出中斷異常會清除線程的中斷狀態,因此如果異常處理不當,那么線程被中斷的信息將會丟失。相反,中斷應該被重新拋出——立即或者在清理方法的狀態之后——或者應該通過調用Thread.interrupt()來重新中斷線程,即使這是單線程的應用程序。任何其他的操作過程都有延遲線程關閉的風險,並且丟失了線程被中斷的信息——線程很可能沒有完成它的任務。

類似地,也應該傳播ThreadDeath異常。根據它的JavaDoc:

如果ThreadDeath異常被一個方法捕獲,那么它被重新拋出是很重要的,這樣線程就會結束。

不符合要求的代碼如下:


public void run () {
  try {
    while (true) {
      // do stuff
    }
  }catch (InterruptedException e) { // Noncompliant; logging is not enough
    LOGGER.log(Level.WARN, "Interrupted!", e);	// catch塊中只是打印了異常日志,相當於忽略了這個異常。
  }
}

解決方案

//Compliant Solution
public void run () {
  try {
    while (true) {
      // do stuff
    }
  }catch (InterruptedException e) {
    LOGGER.log(Level.WARN, "Interrupted!", e);
    // 恢復中斷狀態
    Thread.currentThread().interrupt();
  }
}

枚舉字段不應有public修飾的setter方法

enum通常被視為常量,但是enum帶有public字段或public的setter方法的不僅是非常量的,而且還容易受到惡意代碼的攻擊。理想情況下,枚舉字段應該用private修飾或者在構造器中賦值,但如果不可能,則應盡可能降低其可見性

反例

public enum Continent {

  NORTH_AMERICA (23, 24709000),
  // ...
  EUROPE (50, 39310000);

  public int countryCount;  // 不合理
  private int landMass;

  Continent(int countryCount, int landMass) {
    // ...
  }

  public void setLandMass(int landMass) {  // 不合理
    this.landMass = landMass;
  }

規范寫法

public enum Continent {

  NORTH_AMERICA (23, 24709000),
  // ...
  EUROPE (50, 39310000);

  private int countryCount;
  private int landMass;

  public Continent(int countryCount, int landMass) {
    // ...
  }
    
  void setCountryCount(int countryCount){
      this.countryCount = countryCount;
  }
    
  public getCountryCount(){
      return countryCount;
  }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM