2016-04-08 54 views
0

考慮以下的調整。用戶可以輸入諸如30D,90D,180D,360D,1M,3M,6M,12M,1Y (D =日,M =月,Y =年)之類的東西。「利用」java調用值是明智的

我想用以下兩種方法計算月數。

private int getLengthOfPeriodInMonths(Integer lengthOfPeriod, String unitOfPeriod) { 
     int periodInMonths = lengthOfPeriod; 
     if ("D".equals(unitOfPeriod)) { 
      periodInMonths = lengthOfPeriod/30; 
     } else if ("Y".equals(unitOfPeriod)) { 
      periodInMonths = lengthOfPeriod * 12; 
     } 
     return periodInMonths; 
    } 

    private int getLengthOfPeriodInMonths(Integer lengthOfPeriod, String unitOfPeriod) { 
     if ("D".equals(unitOfPeriod)) { 
      lengthOfPeriod = lengthOfPeriod/30; 
     } else if ("Y".equals(unitOfPeriod)) { 
      lengthOfPeriod = lengthOfPeriod * 12; 
     } 
     return lengthOfPeriod; 
    } 

由於Java的可與呼叫按值與作爲值傳遞一個參考lengthOfPeriod不會外部改變的方法的。我不確定什麼更適合使用。

我知道這種方法可以通過使用enum Periods或類似的東西來重構。但我們不要在此討論這一點。

+0

你能解釋一下什麼是應該發生在這裏? – SomeJavaGuy

+0

做哪一個讓你的代碼更清晰。對我來說,他們都很好。 – khelwood

+0

我認爲可能有一個一般問題:程序員可能會改變第二種方法中的lengthOfPeriod(通過setter),這可能會改變此方法之外的代碼。 – Chris311

回答

3

分配給方法參數不是一個好主意(他們應該已經在默認情況下作爲最終的恕我直言)。如果你真的想避免額外的變量(不是真的有區別),你可以把回報放在你的if子句中。

但不要將參數用作「自動局部變量」。它可能很難看到錯誤,並且不會讓代碼更具性能。

+0

我喜歡這個答案。你能否提供一個會產生錯誤的例子?在傳遞的引用中使用setter-call時,你的意思是什麼? – Chris311

+0

@ Chris311 *「你能提供一個例子來說明它會產生一個bug嗎?」*例如'public void setBlub(String blub){blub = blub;}'這裏程序員將參數賦值給自己,而不是使用領域。或者當程序員認爲,重新分配參數將反映到調用方法,如:'String blub; setBlub(泡殼); .... public void setBlub(String blub){blub =「default」; }'。通過設置參數'final',你可以避免這個問題。 – Tom

+1

@ Chris311好吧,不是特別的,但當然這也是一個潛在的問題。大多數方法*不會*分配給參數,因此如果您要更改方法,則更容易忽視。如果參數需要以某種方式進行預處理,那麼當它們具有最初的參數時,會更加一致,並且可以使用局部變量。 – Kayaman

0

唯一的區別是您在第一個方法中使用自己的變量int periodInMonths = lengthOfPeriod;。但這不是必要的!

您可以使用第二個..它做它應該做的!

int lengthOfPeriodInMonths = getLengthOfPeriodInMonths(lengthOfPeriod, unitOfPeriod); 

,你必須計算出INT存儲在lengthOfPeriodInMonths

PS的方法之外:該調用

lengthOfPeriod = lengthOfPeriod/30; 

相當於

lengthOfPeriod = new Integer(lengthOfPeriod/30); 

(看「自動拳擊「在Java)。

因此,如您所說,Java使用call-bay-value。在此調用中變量lengthOfPeriod被分配了一個新的引用。所以這個計算會在方法之外丟失!這就是爲什麼你必須返回新計算的值!

+0

這正是我已經知道的,但放棄使用局部變量是明智的嗎? – Chris311

+0

是的,因爲你的程序的執行速度稍慢一點,它會減少你的工作內存等;)AND:爲什麼添加一些不需要的東西? – mrbela

+1

@mrbela它對性能沒有影響。這就是所謂的*微型優化*,你專注於那些真正無關緊要的事情,但可能會編寫錯誤的代碼。代碼清晰度遠遠超過「保存」局部變量。最好把注意力集中在比「想要使用1個變量還是2個」更重要的事情上。 – Kayaman

0

首先建議:永遠不要修改方法參數。他們應該始終反映方法用戶傳遞的價值。第二個建議:如果有人建議你永遠不要做某些事情,特別是如果他或她使用「永遠不會」這個短語,請用一粒鹽來聽取他或她的建議。沒有例外的規則(從來沒有;-)。這些規則是偉大的經驗法則,但總是使用自己的判斷。選擇你認爲更清晰的解決方案。我知道某些情況下,我發現修改方法參數比替代方法更具可讀性。

例如,有時您可能希望允許該方法的用戶將null傳遞給方法,但將其替換爲某個默認值。我發現下面的方法

public void doSomething(String s) { 
    if (s == null) s = ""; 
    System.out.println(s); 
} 

不是引入一個局部變量只以包括缺省值更清楚:

public void doSomething(final String s) { 
    String sOrEmpty = s == null ? "" : s; 
    System.out.println(sOrEmpty); 
}