2016-04-08 7 views
0

次のような方法を検討してください。ユーザーは 30D、90D、180D、360D、1M、3M、6M、12M、1Y (D =日、M =月、Y =年)のようなものを入力できます。Javaのcall-by-valueを「悪用する」ことは賢明でしょうか

次の2つの方法で月数を計算します。 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; 
    } 

lengthOfPeriod方法の外に変更されません。私は使用するのがより適切であるか分かりません。

このメソッドは、enum Periodsなどを使用してリファクタリングできます。しかしここでこれについて議論してはいけません。

+0

はあなたがここで起こることになっているかを説明できます。私は、デフォルト値が含まれるように、ローカル変数を導入するよりもはるかに明確に次のような方法

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

を見つけますか? – SomeJavaGuy

+0

コードを明確にするかどうかを指定します。私にとって、彼らはどちらも大丈夫です。 – khelwood

+0

私は1つの一般的な問題があると思います:プログラマは2番目のメソッドでlengthOfPeriod(setterによる)を変更する可能性があり、このメソッドの外部でコードが変更される可能性があります。 – Chris311

答えて

3

メソッドパラメータを割り当てることは良い考えではありません(また、デフォルトのIMHOによって最終的に行われているはずです)。あなたが本当に余分な変数を避けたいのであれば(実際に違いがないわけではない)、if節に戻り値を入れることができます。

しかし、パラメータを「自動ローカル変数」として使用しないでください。バグが見つからなくなることがあり、コードの実行能力が向上しません。

+0

私はこの答えが好きです。バグを生成する例を教えてください。渡されたリファレンスでセッターコールを使用する場合を意味しますか? – Chris311

+0

@ Chris311 * "バグを生成する例を提供できますか?" *例えば、 '' public void setBlub(String blub){blub = blub;} 'のように、フィールド。プログラマが考えると、パラメータを再割り当てすると、以下のような呼び出しメソッドに反映されます: 'String blub; setBlub(blub); .... public void setBlub(String blub){blub = "デフォルト"; } '。パラメータを 'final'にすることで、この問題を回避できます。 – Tom

+1

@ Chris311もちろん、それは潜在的な問題でもあります。ほとんどのメソッド*はパラメータに割り当てられていないため、メソッドを変更している場合は見落としやすくなります。パラメータが元々あったときに一貫性があり、パラメータを何らかの方法で前処理する必要がある場合はローカル変数です。 – Kayaman

0

唯一の違いは、最初の方法で独自の変数int periodInMonths = lengthOfPeriod;を使用することです。しかし、これは必要ではありません!

2番目のものを使用することができます。

int lengthOfPeriodInMonths = getLengthOfPeriodInMonths(lengthOfPeriod, unitOfPeriod); 

、あなたがlengthOfPeriodInMonths

PSに保存されている方法の外で計算int型を持っている:この呼び出し

lengthOfPeriod = lengthOfPeriod/30; 

lengthOfPeriod = new Integer(lengthOfPeriod/30); 

と等価である(自動」に見えますボクシング ")。

あなたが言ったように、Javaはcall-bay-valueを使用します。このコールでは、変数lengthOfPeriodに新しい参照が割り当てられます。だから、この計算はメソッドの外で失われるでしょう!だからあなたは新しく計算された値を返さなければなりません!

+0

これは私がすでに知っていることですが、ローカル変数を使わないのは賢明ですか? – Chris311

+0

はい、あなたのプログラムの実行がちょっとちょっと早く、作業メモリなどを節約しているからです);そして:なぜ不要なものを追加するのですか? – mrbela

+1

@mrbelaパフォーマンスには影響しません。 *マイクロ最適化*と呼ばれるものです。ここでは、実際には関係のないものに集中しますが、代わりに悪いコードを書くことがあります。コードの明快さは、ローカル変数を「保存」することよりもはるかに重要です。 「1変数か2変数を使うべきか」と考えるよりも、実際に重要なことに集中する方が良いでしょう。 – Kayaman

0

最初のアドバイス:決してメソッドパラメータを変更しないでください。これらは、メソッドのユーザーが渡す値を常に反映する必要があります。

第2の助言:特に誰かが決して何かをしないことをアドバイスしている場合、特に「今まで決して」というフレーズを使用していない場合は、塩分で助言を受けてください。例外のないルールはありません(これまで決してありません;-)。このようなルールは大雑把なルールですが、常に自分の判断を使用してください。より明確に思えるソリューションを選択してください。私は、メソッドのパラメータを変更することが、代替メソッドよりも読みやすくなっていることが判明した状況を知っています。

たとえば、メソッドのユーザーがnullをメソッドに渡すことを許可することができますが、それをいくつかのデフォルト値に置き換えることができます。

public void doSomething(final String s) { 
    String sOrEmpty = s == null ? "" : s; 
    System.out.println(sOrEmpty); 
} 
関連する問題