簡體   English   中英

Java構造函數和簡單setter中參數命名的最佳實踐

[英]Best practice for parameter naming in Java constructors and simple setters

對於簡單的構造函數和setter, Java中的參數是否有標准的可接受約定?

我已經看到了C ++的答案 ,但兩個社區的實踐經常不同)

假設我有一個帶有foo字段的C類。

我經常看到以下三個選項:

1)使用帶有下划線的實際字段名稱:

public C(Type foo_)
{
   foo = foo_;
}

public void setFoo(Type foo_)
{
   foo = foo_;
}

2)使用實際的字段名稱,只需在設置中使用“this”:

public C(Type foo)
{
   this.foo = foo;
}
public void setFoo(Type foo)
{
   this.foo = foo;
}

3)完全不一致的事情,如:

public C(Type bar)
{
   this.foo = bar;
}
public void setFoo(Type bar)
{
   this.foo = bar;
}

我傾向於使用2,但我想知道什么是正確的做法。

方案二是最常見的。 在Java中,使用無意義的名稱前綴或后綴來區分實例變量和局部變量的參數被認為是不好的做法。 但名稱本身沒有慣例。 使用任何名稱使代碼最容易理解。

我也看到選項2是最常見的選項:

int importance;

public int getImportance()
{
    return importance;
}

public void setFoo(int importance)
{
    this.importance = importance;
}

Eclipse和Netbeans等IDE將自動以上述格式編寫getter和setter。

使用此方法有一些優點:

不在字段名稱中使用下划線( _ )字符 - 不建議將非下划線用於非常量字段名稱。

除了常量的標識符之外,不建議在標識符中使用下划線字符。

The Java Tutorials的Variables頁面提到了關於下划線的以下內容:

如果變量存儲常量值,例如static final int NUM_GEARS = 6 ,則約定會略有變化,將每個字母大寫並用NUM_GEARS = 6字符分隔后續單詞。 按照慣例,下划線字符從未在別處使用過。

(重點補充。)

由於字段名稱不是常量,根據該頁面上的內容,不應在非常量字段中使用下划線。

IDE可以根據方法參數的名稱自動添加Javadoc注釋,因此在參數列表中使用該字段的名稱將是有益的。

以下是自動生成的Javadoc的示例:

/**
 *
 * @param importance  <-- Parameter name in Javadoc matches
 *                        the parameter name in the code.
 */
public void setImportance(int importance)
{
    this.importance = importance;
}

讓Javadoc反映字段的名稱還有另一個好處 - 具有代碼完成功能的IDE可以使用Javadoc中的字段名稱來自動填寫參數名稱:

// Code completion gives the following:
this.getImportance(importance);

賦予字段名稱和參數名稱含義將使您更容易理解參數實際表示的內容。

這些是我目前可以提出的一些優點,我相信它很可能是在Java中命名參數的最常用方法。

(1)非常C / C ++。 Java並不傾向於使用前導下划線。

我個人使用(2)幾乎完全。

(3)只是讓你的生活變得困難,因為很難想到成員和參數的兩個有意義但簡潔的名字。

我見過2和3使用最多。 也就是說,答案取決於您所貢獻的代碼庫所接受的標准。 我認為在整個項目中保持一致比為每個Java開發人員提供一個“正確”的答案更重要。

Eclipse代碼生成使用列表中的樣式#2。

我知道當netbeans自動創建getter和setter時,它使用數字2方法。 我個人通常會給變量添加temp,即foo = tempfoo 但正如neesh所說,無論選擇哪種方法,都應盡量保持一致

是選項2是最廣泛使用的; 雖然它有一個嚴重的問題:如果你的參數聲明中有一個拼寫錯誤 - 由於陰影可能會被忽視,例如:

class Whatever { 
  String val;
  Whatever(String va1) { this.val = val; }
  void printMe() { System.out.println(val.toString()); }
  public static void main(String[] args) {
    new Whatever("Hello").printMe();
  }
}

這段代碼編譯得很好; 你需要一秒鍾才能理解那里的錯誤。 如果你有疑問; 把它打印出來; 把它交給你的同事,問他們如果這個類被編譯和執行會發生什么。 我猜:75%+ 不會意識到會拋出NullPointerException。 如果你轉向val和va1的“看起來相同”的字體; 那時沒有人會注意到......

是的,現在您可能會看到有關此問題的警告,或者某些代碼檢查工具會告訴您發生了這種情況; 當然,您的單元測試應該立即找到它。

但是:如果你避免這種模式,並使用前綴或“thatString”,你將永遠不會遇到這個問題。 因此,我真的不明白為什么它如此常用。

所以,我們坐在我們的團隊中,在整理我們的編碼風格指南時,我們說:永遠不要使用選項2。

選項2是大多數Java風格指南推薦的。

我發現谷歌的Java風格指南非常有用:

更新鏈接(Jun-2019): https//google.github.io/styleguide/javaguide.html

或在網上搜索“Google Java Style Guide”

我個人使用foo(Bar parBar)雖然我知道它通常被認為是不良的做法預先或后綴變量名稱。

背后的原因很簡單: 清晰度

現在,如果你調用一個方法foo(Bar bar) ,它可能並不總是直觀的什么bar 實際上的意思。 即使它是,它仍然是一個痛苦的屁股。

this.bar = bar甚至bar = bar更干凈,比bar = parBar更直觀? 我寧願有一個前綴而不是邏輯歧義。

選項2在Java中最常見,但挑剔的Checkstyle不允許您使用此選項,因為本地var的名稱會影響另一個。

因此,大多數使用以下內容:

foo(int thatBar) { this.bar = thatBar; }

使用此選項的唯一問題是其他人可能猜測您在類中使用了var命名條,因為如果不是,則不會為參數命名。

一個邪惡的人只能通過查看方法來使用這些信息來更好地理解你的課程。 但為此你會使用一個重命名所有變量等的混淆器。

雖然從setter返回void很常見,但有時返回實例的引用很方便:

public class Foo {

    String value1, value2;

    public Foo setValue1(String value1) {
        this.value1 = value1;
        return this;
    }

    public Foo setValue2(String value2) {
        this.value2 = value2;
        return this;
    }
}

這允許您鏈接值的設置: new Foo().setValue1("A").setValue2("B");

當您編寫代碼以使界面盡可能清晰時,我總是更喜歡在內部使用字段作為_name ,將其作為方法參數的name ,優雅地將其指定為_name = name 我在Fowler的Refactoring和其他類似的教科書中看到了這一點,雖然我看到了丑陋的機制,比如在內部使用該字段作為name然后使用aName作為方法參數,呃。

方案二。

如果你看到“setFoo(String foo)”定義(例如在javadoc或hover中),你可以合理地期望字段“foo”被設置為參數“foo”的值。 其他名稱可能要求您仔細檢查 - 例如setName(String person)只是將名稱設置為person或者是否會采取其他操作(在人員表中查找名稱等)?

不這樣做的通常原因是你可能會意外地寫

...... foo = foo;

代替

this.foo = foo;

這是一個沒有做任何事情的參數的自我賦值。 現代編譯器捕獲這一點 - 現代IDE在為字段創建setter時生成“this.foo = foo”語句。

在Eclipse中,您可以為字段創建getter和setter,當光標位於相關字段時,使用Ctrl-1。

我使用的約定是用m_作為成員變量的序言; 如:

字符串m_foo;

這樣,很明顯哪些變量是成員,哪些不是。

另外,我的上一家公司在方法中用“the”開頭的所有參數,如:

public doFoo(String theKey,String theRandom){

....

}

它使得很容易不將參數與內部變量混淆。

約定應該是使代碼更容易閱讀,並減少錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM