天天看點

Java代碼注釋

曾經我對“一份好的代碼裡注釋至少要占到一半的份量”這樣話深信不疑,我也不厭其煩的給每一個函數都加上javadoc,對此,我深感自豪;而對于别人寫代碼不加注釋的“壞習慣”,我深表遺憾。然而當我讀完Robert的“注釋”一節,我已經懊惱不已,并且我已經開始對我的代碼進行稽核,再次優化。我已經開始遵守“别給糟糕的代碼加注釋–重新寫吧”這條準則。

也許你是一個好人,會對代碼進行不斷的優化改進,然而你經常會把注釋忽略掉,就如同下面這樣:

/**
  * 集合競價.
  *
  * @param orderFromClient
  * @return
  */
 private Message callAuction(SelfOrder orderFromClient, long b, JadeInfo jadeInfo) {      

方法參數已經改變了,然而javadoc的注釋中依然隻有一個參數。

我個人已經深深地被Robert影響了,代碼才能最忠誠的告訴它在做什麼,而不是注釋。但是我們很多人,包括在看這本書之前的我,認為寫得一手好注釋的程式員才是好程式員,當然這不包含那些隻會寫糟糕代碼的人。

用代碼來闡述

我們來比較一下這兩種代碼:

public void pause() {

  if (isNotAction()) {
   return;
  }
}

/**
  * 節假日或當天無交易商品,伺服器不執行操作
  */
 private boolean isNotAction() {
if (isHoliday || !hasTradingJade) {
   return true;
  }

  return false;
 }      
public void pause() {
// 節假日或當天無交易商品,伺服器不執行操作
if (isHoliday || !hasTradingJade) {
   return ;
  }
}      

我認為第一種更好,因為節假日以及無交易商品,就說明伺服器當日不需要運作,那麼用isNotAction來表明會更好。

好注釋

對意圖進行解釋

/* 
  * 按照使用者id對資金變化量進行排序,進而保證在多線程同時更新資金字段時,不發生死鎖
  */
 @Override
 public int compareTo(VarialMoneyUser o) {
  return this.getUid().compareTo(o.getUid());
 }      

這樣的注釋,我認為還不錯,說明了使用compare的意圖。

TODO注釋

有的時候,我們的需要做一些事情,而我們暫時沒有做,那麼就可以使用TODO,這樣IDE就會管理到這些TODO,當然還有FIXME标記,表明我們有些問題暫時不知道怎麼優化、改善。

trade.setDjzj(BigDecimal.valueOf(0));// FIXME 當機資金待實作

// TODO 計算賬戶的盈虧,根據風險控制等級,标示次日需要提醒、限制交易、強制平倉的賬戶

但是需要注意,定期的回頭檢查,eclipse提供以下圖檔的功能,你要删除那些無用的TODO

Java代碼注釋

壞注釋

喃喃自語

public void dailyUpdateSystemData() {
  // 每日更新時進行一次會員資訊更新
  AllMembercoes.init();      

以上的注釋毫無必要。

多餘的注釋

/**
  * @Description: 擷取指定日期的行情日報
  */
 public QuotationDailyReport getQuotationReportByDateAndScode(QuotationDailyReport report);

 /**
  * @Title: addQuotationReport
  * @Description: 添加行情日報
  * @param tradeReport
  * @return
  */
 public int addQuotationReport(QuotationDailyReport tradeReport);

 /**
  * @Title: getLastQuotationReport
  * @Description: 擷取指定商品上一次的行情日報資訊
  * @param map
  * @return
  */
 @SuppressWarnings("rawtypes")
 public QuotationDailyReport getLastQuotationReport(Map map);      

這些注釋比沒有注釋還可怕,其實看方法名稱,都知道要做什麼,加上注釋後反倒浪費時間。

ps:我之前非常喜歡加這種注釋,我恨不得在每一個方法上面加上注釋,但是自從我明白了,方法名本身就應該代表了方法要做什麼以後,我深惡痛絕自己以前荒唐的行為。

誤導性注釋

這個非常的可怕,很多時候,注釋和代碼表達的意思完全相反,或者牛頭不對馬嘴,總之很容易讓人迷惑。

// 12點後設定isreload為true,重新加載配置,

private void updateReloadStatusTrue() {

這個注釋在本意上應該是非常友好的,提示這個方法是在12點以後執行的,但是我上下文翻看,壓根找不到任何12點的資訊。

這樣會好一點

/**
  * 設定isreload為true,表明配置服務、商品服務可以重新加載了
  */
 private void updateReloadStatusTrue() {
  reload = true;
  ConfigService.isReload = reload;
  JadeInfoService.isReload = reload;
 }      

循規蹈矩的注釋

哦,這種注釋多發生在方法上,我曾經就非常熱衷于這樣的注釋,現在我才知道其可怕之處。

/**
  * @Title: updateQuotation
  * @Description: 修改指定商品的行情資訊
  * @param quotation
  */
 public void updateQuotation(Quotation quotation) {
  this.quotationMapper.updateQuotation(quotation);
 }      

title、param的注釋有兩種壞處

非常多餘,難道方法本身不能告訴我嗎?

阻礙重構,當方法名、參數名需要重構或者添加參數時注釋是不會緊随變更的。

日志式注釋

以前我們特别喜歡在代碼裡加上以下這樣注釋

// start update by maweiqing
      // 如果能夠接收到消息,說明用戶端已經進行操作了,那麼就更新session的時間
      data = CryptUtil.encrypt(data, SessionManager.getSession(getSession().getSessionId())
        .getEncryptKey());
      // end update by maweiqing 2015-05-27      

看到Robert的建議後,我真的才恍然大悟,這樣的代碼還要SVN的代碼管理器幹嘛?SVN在送出的時候自然會讓你輸入你的修改理由、以及自動顯示署名、日期的。

廢話注釋

// 辨別列

private Integer id;

// 使用者id

private Integer userId;

// 使用者名

private String userName;

這樣的注釋完全沒有必要,你認為有嗎?

/**
  * @return the id
  */
 public Integer getId() {
  return id;
 }
 /**
  * @param id
  *            the id to set
  */
 public void setId(Integer id) {
  this.id = id;
 }      

還有利用IDE生成的這種bean注釋,我真後悔自己當初為什麼會這樣想,加上這樣的注釋讓自己顯得專業嗎,顯然适得其反。

位置标記

雖然我暫時沒有在自己的代碼中找到,但是之前我這樣做過。

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

//aaaaaaaaaaaaaaaaaaaa

注釋掉的代碼

哦,顯然我又中招了,之前我特别喜歡把那些所謂還有作用的代碼留在代碼裡,及時壓根就是錯誤的。但是自從我看到Jeff的部落格後,我就開始删掉了那些注釋掉的代碼,今天再看到Robert的文章,感覺這些偉大的程式員他們都會有這樣相似的真理。

如果你的代碼中還有這樣的注釋,請盡快删掉吧,危害太大。

總結:我覺得Robert的文章越來越深入的影響着我,讓我改變了很多陋習。

繼續閱讀