Javaはデフォルトのパラメーター値をサポートしていますか?


1661

次の構造を持つJavaコードに出くわしました。

public MyParameterizedFunction(String param1, int param2)
{
    this(param1, param2, false);
}

public MyParameterizedFunction(String param1, int param2, boolean param3)
{
    //use all three parameters here
}

C ++ではパラメーターにデフォルト値を割り当てることができることを知っています。例えば:

void MyParameterizedFunction(String param1, int param2, bool param3=false);

Javaはこの種の構文をサポートしていますか?この2つのステップの構文が望ましい理由はありますか?


85
いいえ。ただし、Builderパターンが役立ちます。
デイブジャービス

50
私はこの機能が本当に恋しいです。関数またはコンストラクタに追加のパラメータを取るために、既存のコードを変更するとき、それは多くのことができます
Jatin

4
@Jatin Eclipseの「メソッドシグネチャの変更」リファクタリングを使用すると、パラメータを追加して、既存の呼び出し側が使用するデフォルト値を提供できます。
Erwin Bolwidt 2015年

2
@ErwinBolwidtありがとう。私はAndroid Studioを使用していますが、メソッドをリファクタリングしてデフォルト値を提供するオプションもあります。かなり便利です。
ジャティン

3
@temporary_user_name public MyParameterizedFunction(String param1, int param2)はコンストラクターであり、メソッド宣言ではありません。
Mario Ishac

回答:


955

いいえ、見つかった構造は、Javaがそれを処理する方法です(つまり、デフォルトのパラメーターの代わりにオーバーロードを使用しています)。

コンストラクターについては、オーバーロードが複雑になっている場合は、Effective Java:Programming Language Guideの Item 1のヒント(コンストラクターの代わりに静的ファクトリーメソッドを検討してください)を参照してください。他のメソッドについては、一部のケースの名前を変更するか、パラメーターオブジェクトを使用すると効果があります。これは、区別が難しいほど複雑な場合です。明確なケースは、数値とタイプだけでなく、パラメータの順序を使用して区別する必要がある場合です。



135
@JarrodRoberson:静的なファクトリーメソッドはと同じくらい有害ですnew。彼らはされて使用され、すべての時間を新しいコードで。単純な値オブジェクトのビルダーは、多くの場合、過剰設計の結果です。
Lii

12
@JarrodRoberson:コンパイラを介して正しい使用を強制する興味深い方法です。共有していただきありがとうございます。今後の投稿のための友好的な提案:300行のコメント化されていないソースコードは、ほとんどの人にとっておそらく消化するのに少し多くなります(結局、コードは書くより読むのが難しいです)。再度、感謝します!
クリスチャンAichinger 2016年

17
@JarrodRoberson:いいですね、楽しみにしています!私が伝えたかったこと:ブログの読者として、何が起こっているのかを簡潔に説明した50行の例は、コンテキストなしで300行以上を助けてくれます。
Christian Aichinger、2016年

8
@ user177800同意しない-純粋な関数として記述された静的メソッドは完全に問題ありません。静的関数が状態を変化させて問題になるときです...
Levi Fuller

642

いいえ。ただし、このスタックオーバーフローの回答で説明されているように、ビルダーパターンを使用できます。

リンクされた回答で説明されているように、ビルダーパターンを使用すると、次のようなコードを記述できます。

Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
                 .name("Spicoli")
                 .age(16)
                 .motto("Aloha, Mr Hand")
                 .buildStudent();

一部のフィールドは、デフォルト値を持つか、オプションである場合があります。


142
最後に、ビルダーパターンの2ページ未満の優れた例。
nevvermind

14
不思議なことに、ビルダーパターンを使用するときにビルダークラスが必要なのはなぜですか。私はStudent s1 = new Student()。name( "Spicolo")。age(16).motto( "Aloha、Mr Hand);のことを
考えていました。– ivanceras

52
@ivanceras:クラスに必須フィールドがあり、それらのクラスを無効な状態でインスタンス化できないようにしたい場合に関係します。だから、あなたが言ったばかりならStudent s1 = new Student().age(16);、それはあなたに名前のない学生を残すでしょう、それは悪いかもしれません。それが悪くないなら、あなたの解決策は大丈夫です。
Eli Courtwright、2013

57
@ivanceras:もう1つの理由は、作成後にクラスを不変にしたい場合があるため、その中に値を変更するメソッドを必要としないことです。
ジュール

3
@ivanceras:私はビルダーを3つの目的で使用しました-複数の引数と流暢な初期化、不変性を排除し、最も重要なのはbuild()メソッドでドメインオブジェクトを検証するように感じていることです。無効な場合にオブジェクトインスタンスを作成する理由。上記の場合のようなファクトリメソッドbuildFreshman()、buildSenior()など
Abhijeet Kushe

485

Javaのデフォルトパラメータをシミュレートする方法はいくつかあります。

  1. メソッドのオーバーロード。

    void foo(String a, Integer b) {
        //...
    }
    
    void foo(String a) {
        foo(a, 0); // here, 0 is a default value for b
    }
    
    foo("a", 2);
    foo("a");

    このアプローチの制限の1つは、同じタイプの2つのオプションパラメーターがあり、それらのいずれかを省略できる場合は機能しないことです。

  2. Varargs。

    a)すべてのオプションパラメータは同じタイプです。

    void foo(String a, Integer... b) {
        Integer b1 = b.length > 0 ? b[0] : 0;
        Integer b2 = b.length > 1 ? b[1] : 0;
        //...
    }
    
    foo("a");
    foo("a", 1, 2);

    b)オプションパラメータのタイプは異なる場合があります。

    void foo(String a, Object... b) {
        Integer b1 = 0;
        String b2 = "";
        if (b.length > 0) {
          if (!(b[0] instanceof Integer)) { 
              throw new IllegalArgumentException("...");
          }
          b1 = (Integer)b[0];
        }
        if (b.length > 1) {
            if (!(b[1] instanceof String)) { 
                throw new IllegalArgumentException("...");
            }
            b2 = (String)b[1];
            //...
        }
        //...
    }
    
    foo("a");
    foo("a", 1);
    foo("a", 1, "b2");

    このアプローチの主な欠点は、オプションのパラメーターの型が異なる場合、静的型チェックが失われることです。さらに、各パラメーターの意味が異なる場合は、それらを区別する方法が必要です。

  3. ヌル。前のアプローチの制限に対処するには、null値を許可してから、メソッド本体の各パラメーターを分析します。

    void foo(String a, Integer b, Integer c) {
        b = b != null ? b : 0;
        c = c != null ? c : 0;
        //...
    }
    
    foo("a", null, 2);

    すべての引数の値を指定する必要がありますが、デフォルトの値はnullの場合があります。

  4. オプションのクラス。このアプローチはnullに似ていますが、デフォルト値を持つパラメーターにJava 8 Optionalクラスを使用します。

    void foo(String a, Optional<Integer> bOpt) {
        Integer b = bOpt.isPresent() ? bOpt.get() : 0;
        //...
    }
    
    foo("a", Optional.of(2));
    foo("a", Optional.<Integer>absent());

    オプションは、呼び出し元に対してメソッドコントラクトを明示的にしますが、そのようなシグネチャは冗長すぎる場合があります。

  5. ビルダーのパターン。ビルダーパターンはコンストラクターに使用され、別のビルダークラスを導入することで実装されます。

     class Foo {
         private final String a; 
         private final Integer b;
    
         Foo(String a, Integer b) {
           this.a = a;
           this.b = b;
         }
    
         //...
     }
    
     class FooBuilder {
       private String a = ""; 
       private Integer b = 0;
    
       FooBuilder setA(String a) {
         this.a = a;
         return this;
       }
    
       FooBuilder setB(Integer b) {
         this.b = b;
         return this;
       }
    
       Foo build() {
         return new Foo(a, b);
       }
     }
    
     Foo foo = new FooBuilder().setA("a").build();
  6. マップ。パラメータの数が多すぎて、それらのほとんどに対してデフォルト値が通常使用される場合、名前/値のマップとしてメソッド引数を渡すことができます。

    void foo(Map<String, Object> parameters) {
        String a = ""; 
        Integer b = 0;
        if (parameters.containsKey("a")) { 
            if (!(parameters.get("a") instanceof Integer)) { 
                throw new IllegalArgumentException("...");
            }
            a = (String)parameters.get("a");
        } else if (parameters.containsKey("b")) { 
            //... 
        }
        //...
    }
    
    foo(ImmutableMap.<String, Object>of(
        "a", "a",
        "b", 2, 
        "d", "value")); 

これらのアプローチのいずれかを組み合わせて、望ましい結果を得ることができることに注意してください。


1
良い説明。このように使用される戻り値を見たことがありません。5)の目的は何return thisですか?また、FooBuilder().setA("a").build();(定義により)コンストラクタが最初に呼び出されFooBuilder()て値が返されるのではない.setA("a"):ですか?これは、呼び出される機会を得られないことを意味しませんか?
Celeritas 14

3
@Celeritas return thisは、メソッドが呼び出されたのと同じオブジェクトを返します(例ではFooBuilder)。これによりnew FooBuilder().setA(..).setB(..).setC(..)、別のステートメントで各メソッドを呼び出すのではなく、同じオブジェクトに作用する1つのステートメントでメソッドを連鎖させることができます。
ADTC、2014

2
@Celeritas new FooBuilder()FooBuildersetAメソッドが呼び出されたオブジェクトを返します。通りsetBと呼ばれていない、this.bデフォルト値を保持します。最後に、buildこのFooBuilderオブジェクトでメソッドが呼び出されます。このbuildメソッドはFoo、変数に設定されたオブジェクトを作成して返しますFoo fooFooBuilderオブジェクトが変数に格納されていないことに注意してください。
ADTC 2014

アノテーションは、デフォルトのパラメータを作成するためにも使用でき、ポリモーフィックコレクションに必要な場合に最も役立ちます。 docs.oracle.com/javase/tutorial/java/annotations/declaring.html
Martin Spamer 2015年

1
2つの質問で同じ回答に900以上の賛成票を投じます。私は感銘を受けました:stackoverflow.com/questions/965690/java-optional-parameters/…–
AdamMc331

256

残念ながら、違います。


34
悲しいですか?これを行うと、あいまいになる可能性のある関数シグネチャが導入されます。
Trey

69
@Trey:デフォルトのパラメータを持つ言語は、あまり説得力がないため、関数のオーバーロードを回避することがよくあります。あいまいさはありません。それに加えて、Scalaは2.8で機能を追加し、あいまいさの問題を何とか解決しました(互換性の理由でオーバーロードを維持したため)。
PhiLho、

32
パラメータのデフォルトが関数のオーバーロードを防ぐ方法がわかりません。たとえばC#では、オーバーライドが可能で、デフォルトの初期化も可能です。理由は、制限ではなく任意の選択のようです。
FlavorScape 2013年

51
ええ、コンパイラにいくつかの追加作業をさせ、代わりに私たち全員に100000のオーバーロードを作成させて、ライブラリのユーザーに便宜を図ります。良いアイデア。

28
@ user562566:Javaプロジェクトに取り組んでいるときはいつでも、Java開発者は1日あたり何行のコードを生成するかによって支払い/測定されているという印象を受けます
Mark K Cowan

83

残念ながらそうです。

void MyParameterizedFunction(String param1, int param2, bool param3=false) {}

Java 1.5では次のように書くことができます。

void MyParameterizedFunction(String param1, int param2, Boolean... params) {
    assert params.length <= 1;
    bool param3 = params.length > 0 ? params[0].booleanValue() : false;
}

しかし、コンパイラが生成することについてのあなたの気持ちに依存すべきかどうか

new Boolean[]{}

呼び出しごとに。

デフォルト設定可能な複数のパラメータの場合:

void MyParameterizedFunction(String param1, int param2, bool param3=false, int param4=42) {}

Java 1.5では次のように書くことができます。

void MyParameterizedFunction(String param1, int param2, Object... p) {
    int l = p.length;
    assert l <= 2;
    assert l < 1 || Boolean.class.isInstance(p[0]);
    assert l < 2 || Integer.class.isInstance(p[1]);
    bool param3 = l > 0 && p[0] != null ? ((Boolean)p[0]).booleanValue() : false;
    int param4 = l > 1 && p[1] != null ? ((Integer)p[1]).intValue() : 42;
}

これはC ++構文と一致し、パラメーターリストの最後にある既定のパラメーターのみを許可します。

構文以外にも、渡されたデフォルト可能パラメーターのランタイム型チェックと、コンパイル時にC ++型がそれらをチェックするという違いがあります。


14
賢いですが、varargs(...)は最後のパラメーターにのみ使用できます。これは、デフォルトのパラメーターをサポートする言語が提供するものよりも制限があります。
CurtainDog 2010年

6
それは賢いですが、C ++バージョンに比べると少し面倒です
誰か誰か

5
JavaはC#などが許可するようにオプションのデフォルトパラメーターが必要です...構文は明白であり、可能な組み合わせをすべてコンパイルするだけでもこれをかなり簡単に実装できると思います...なぜそれらが言語に追加されていないのか想像できませんまだ!
jwl

10
assert本番用コードを使用することはできません。例外をスローします。
Michael Dorst 2013年

5
-1これは本当にvarargsの目的ではありません。これはハックです。-この場合、オーバーロードを使用すると読みやすくなります(3つの余分な文字は5つの余分なソース行よりも読みやすいので残念です...)。-しかし、Javaはデフォルトのパラメータをサポートしていません。
BrainSlugs83 2015

38

いいえ。ただし、非常に簡単にエミュレートできます。C ++の内容:

public: void myFunction(int a, int b=5, string c="test") { ... }

Javaでは、オーバーロードされた関数になります。

public void myFunction(int a, int b, string c) { ... }

public void myFunction(int a, int b) {
    myFunction(a, b, "test");
}

public void myFunction(int a) {
    myFunction(a, 5);
}

前述したように、デフォルトのパラメーターは関数のオーバーロードであいまいなケースを引き起こしていました。それは単に真実ではありません。C++の場合に見ることができます。はい、多分あいまいなケースを作成する可能性がありますが、これらの問題は簡単に処理できます。これは単にJavaで開発されなかったためです。おそらく、作成者がC ++のようにはるかに単純な言語を望んでいたためです。しかし、私たちのほとんどは、その単純さのために彼がJavaを使用するとは考えていません。


8
C#のデフォルト値表記の主な考え方は、この定型的なコーディングを回避し、多数ではなく1つだけのコンストラクターを持つことです。
コリャイヴァンコフ2017年

1
@KolyaIvankov C#はわかりませんが、推論が同じであるC ++は知っています。何が良いかわかりませんが、C ++ / C#の場合、実際には同じ定型コードがコンパイラーによって生成され、最終的なバイナリに入ります。
peterh-2017年

5
(特に)すべてのプログラミング言語は、アセンブラのボイラープレートを回避するための手段です。問題は、それが便利な機能を提供するかどうかだけです。
Kolya Ivankov 2017年

2
最初の文は修辞的な質問です。2文目の「質問」という言葉は、1文目の修辞的な質問とは関係ありません。
Kolya Ivankov 2017年

1
より具体的に言えば、言語は、私たちが書いたものを制御できる方法でプログラムを書くことができるツールであり、コンパイルは、私たちが望んでいるものをマシンに伝える方法です。ボイラープレートを回避できるツールであれば、さらに便利です。実際、gnaviは、C#で許可されているため、回答として提案する定型コードのタイプを正確に回避できるかどうかを尋ねました。
Kolya Ivankov 2017年

24

これは、JVMで実行され、Javaプログラムと互換性のあるScalaで行うことができます。 http://www.scala-lang.org/

すなわち

class Foo(var prime: Boolean = false, val rib: String)  {}

58
まったく新しい機能を使用して、あまり一般的でない機能を入手しますか?
om-nom-nom 2012

8
@ om-nom-nom:Javaは存在すべきではありません。機能が使用されていないと言うことは、誰も必要としないことと同等であり、Javaが発明される前は人気がなかったと言うことは、Goslingが設計を開始すべきではないことを意味します。
Val

28
@ヴァルは、これは大砲で鳥を撃つようなものだと言っています
om-nom-nom

8
それはOPの質問とは何の関係もありません
destan

コトリンでも動作します。そしてGroovy。そしてC#。そしてJavascript。そして、実際の人々と問題のために作られた他のほとんどすべての言語。
スパイロ

17

いいえ、ただし、これを実装する最も簡単な方法は次のとおりです。

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    param3 = param3 == null ? false : param3;
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

または三項演算子の代わりに、以下を使用できますif

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    if (param3 == null) {
        param3 = false;
    }
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

2
はい、このアプローチは他の代替案から最高のようです。それでも、Javaがデフォルト値を採用するとよいでしょう。Kotlinはこれが可能であることを示したので、なぜOracleが現代に移行せず、1990年代であるかのようにJavaの設計を続けています。:D
シェビー

13

ここで明白なことを述べているかもしれませんが、なぜ「デフォルト」パラメータを自分で実装しないのですか

public class Foo() {
        public void func(String s){
                func(s, true);
        }
        public void func(String s, boolean b){
                //your code here
        }
}

デフォルトでは、次のいずれかを使用します

func("my string");

デフォルトを使用したくない場合は、

func("my string", false);

11
ポスターは、この(むしろ醜い)パターンを回避できるかどうかを尋ねました... ;-)より最近の言語(c#、Scalaなど)では、追加のコード行を作成するだけの余分なオーバーロードは必要ありません。しばらくの間、varargsを使用できます(静的int max(int ... array){})が、非常に醜い回避策にすぎません。
Offler

2
オーバーロードは見苦しくなく、さまざまなシグネチャを持つさまざまなメソッド呼び出しがさまざまな機能を実行できるなど、多くの利点があります。 //This is better public class Foo() { /* This does something */ public void func(String s){ //do something } /* This does something else with b */ public void func(String s, boolean b){ // b was passed } } //Than this public class Foo() { /* This does something unless b = value, then it does something else */ public void func(String s, boolean b = value){ If (b){ // Do Something } else{ // Do something else } } }
アントニーブース

まあ、別の行動が必要な場合。唯一の違いが計算などのわずかな変更である場合、複数のシグネチャを作成する努力の無駄は確かです。デフォルトはあなたがそれらを必要とするところに意味があります...そして、それがないことは「役に立たない」要件として分類されるべきではありません。
Kapil

@Offlerのデフォルトパラメータは、「現代の言語」とは関係ありません。私は20年前にDelphiでそれらを使用しましたが、おそらくターボパスカルにすでに存在していました。
信じられないほどの月

私はオフラーに同意し、アントニーブースにも同意しません。私はそれが醜いだけでなく、かなり非効率的だと思います。rubyやpythonなどの言語では、デフォルトのパラメーターを使用するのは簡単です。Javaがあなたに必要なことは、回避策を見つける(そして使用する)ことだと思います。nullに対する明示的なチェックは、コマンドラインからも呼び出すことができるので、最も醜い選択のようです(何も指定せず、正常なバリアントを処理します)。演算子のオーバーロードのアプローチは...非常に冗長です(null-checkと比較して少なくとも+3行、コードがより複雑な場合はより多くの行など)。
シェビー

8

Scalaが言及されたように、Kotlinも言及する価値があります。Kotlin関数では、パラメーターにデフォルト値を設定することもでき、他のパラメーターを参照することもできます。

fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
    ...
}

Scalaと同様に、KotlinはJVM上で実行され、既存のJavaプロジェクトに簡単に統合できます。


6

番号。

スマートなデフォルトを持つオブジェクトを渡すことで同じ動作を実現できます。しかし、それはあなたの事件が何であるかによります。


5

いいえ。Javaは単純な言語を作ろうとしたので、一般的には(あまり)構文上の砂糖は多くありません。


26
結構です。厳しい真実は、チームがタイトなスケジュールであり、構文砂糖のための時間がないということです。他になぜconst、そしてgoto実装されていない予約済みキーワードなのでしょうか?—特にconst、私がひどく恋しく思っているものは— final代替品ではなく、彼らはそれを知っていました。—また、実装しないという慎重な決断をしたgoto場合は、キーワードを予約する必要はありません。—そして、Javaチームの後半では、LabelをPascal breakcontinue同じくらい強力なものにすることで騙されましたgoto
マーティン

「シンプルでオブジェクト指向で使い慣れ
mikera

1
tomjenは次のように述べています。「いいえ。一般的にJavaは単純な言語を作ろうとしたので、構文上の砂糖は多くありません」。それで、C ++から多くの不要な機能を削除すると、Javaが単純な言語になり、Javaに可変個のメソッドがある理由を教えてください。なぜ可変引数があるのですか?代わりに単にオブジェクトの配列を使用できる場合は必要ありません。そうですか?varargsは不要なので、言語から削除できます。これにより、現在よりもJavaがシンプルになります。私は正しいですか?各メソッドには無限の名前があるため、オーバーロードも削除できます。

1
そして、それが私たちが単純な言語を取り、実際のJavaプロジェクトを構文とボイラープレートのclusterfuckに変換するものを取得した理由です:-)
matanster

開発者に定型コードと複雑な回避策を強制することは、「簡単」という言葉を理解していません。myFunction(a、b = false、c = 3)、それは私が簡単に呼ぶものです。
スパイロ

5

代わりに:

void parameterizedMethod(String param1, int param2) {
    this(param1, param2, false);
}

void parameterizedMethod(String param1, int param2, boolean param3) {
    //use all three parameters here
}

単一のメソッドを使用することにより、Javaのオプション機能を利用できます。

void parameterizedMethod(String param1, int param2, @Nullable Boolean param3) {
    param3 = Optional.ofNullable(param3).orElse(false);
    //use all three parameters here
}

主な違いは、null入力を許可するためにプリミティブJavaタイプの代わりにラッパークラスを使用する必要があることです。Booleanの代わりにbooleanInteger代わりにintなど。


4

これはサポートされていませんが、いくつかの構文糖でパラメーターオブジェクトパターンを使用するようないくつかのオプションがあります。

public class Foo() {
    private static class ParameterObject {
        int param1 = 1;
        String param2 = "";
    }

    public static void main(String[] args) {
        new Foo().myMethod(new ParameterObject() {{ param1 = 10; param2 = "bar";}});
    }

    private void myMethod(ParameterObject po) {
    }
}

このサンプルではParameterObject、デフォルト値を使用して構築し、クラスインスタンス初期化セクションでそれらをオーバーライドします{ param1 = 10; param2 = "bar";}


3

この解決策を試してください:

public int getScore(int score, Integer... bonus)
{
    if(bonus.length > 0)
    {
        return score + bonus[0];
    }

    return score;
}

3

Javaメソッド呼び出しビルダーを使用して、デフォルト値のビルダーを自動的に生成できます。

@GenerateMethodInvocationBuilderをクラスまたはインターフェースに追加し、@ Defaultをデフォルト値が必要なメソッドのパラメーターに追加するだけです。ビルダーは、注釈で指定したデフォルト値を使用して、コンパイル時に生成されます。

@GenerateMethodInvocationBuilder
public class CarService {
 public CarService() {
 }

 public String getCarsByFilter(//
   @Default("Color.BLUE") Color color, //
   @Default("new ProductionYear(2001)") ProductionYear productionYear,//
   @Default("Tomas") String owner//
 ) {
  return "Filtering... " + color + productionYear + owner;
 }
}

そして、メソッドを呼び出すことができます。

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .invoke(instance);

または、デフォルト値を別の値に設定します。

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .withColor(Color.YELLOW)//
  .invoke(instance);

2

Java 8で機能するhttps://stackoverflow.com/a/13864910/2323964への同様のアプローチは、デフォルトのゲッターでインターフェースを使用することです。これは余計な余白になりますが、モック可能です。実際にパラメーターに注意を向けたいインスタンスがたくさんある場合に最適です。

public class Foo() {
    public interface Parameters {
        String getRequired();
        default int getOptionalInt(){ return 23; }
        default String getOptionalString(){ return "Skidoo"; }
    }

    public Foo(Parameters parameters){
        //...
    }

    public static void baz() {
        final Foo foo = new Foo(new Person() {
            @Override public String getRequired(){ return "blahblahblah"; }
            @Override public int getOptionalInt(){ return 43; }
        });
    }
}

2

これを使用して、値を返すメソッドでこれを使用する方法を理解するのにかなりの時間を費やしてきましたが、これまでの例を見たことがないので、ここに追加すると便利だと思いました。

int foo(int a) {
    // do something with a
    return a;
}

int foo() {
    return foo(0); // here, 0 is a default value for a
}

1

これは私がやった方法です...おそらくあなたの定義されたパラメータに対して「オプションの引数」を持つことほど便利ではありませんが、それは仕事をします:

public void postUserMessage(String s,boolean wipeClean)
{
    if(wipeClean)
    {
        userInformation.setText(s + "\n");
    }
    else
    {
        postUserMessage(s);
    }
}

public void postUserMessage(String s)
{
    userInformation.appendText(s + "\n");
}

文字列だけで同じメソッド名を呼び出すことも、文字列とブール値で呼び出すこともできます。この場合、wipeCleanをtrueに設定すると、私のTextArea内のすべてのテキストが指定された文字列に置き換えられます。wipeCleanをfalseに設定するか、すべて一緒に省略すると、指定されたテキストがTextAreaに追加されます。

また、2つのメソッドでコードを繰り返さないことに注意してください。追加したブール値のみを使用して同じ名前で新しいメソッドを作成することにより、TextAreaをリセットできる機能を追加しているだけです。

デフォルト値などをコーディングする必要があるので、Javaがパラメーターに「オプションの引数」を提供した場合よりも、これは実際には少しクリーンだと思います。この例では、そのいずれについても心配する必要はありません。はい、クラスに別のメソッドを追加しましたが、長期的に見ると控えめな意見のほうが読みやすいです。


1

いいえ、ただし、関数のオーバーロードという形で代替手段があります。

パラメータが渡されなかったときに呼び出されます

void operation(){

int a = 0;
int b = 0;

} 

「a」パラメータが渡されたときに呼び出されます

void operation(int a){

int b = 0;
//code

} 

パラメータbが渡されたときに呼び出されます

void operation(int a , int b){
//code
} 

1

このような6ダース以上の問題があり、最終的には静的なファクトリパターンに到達します。そのための暗号APIを参照してください。説明するのは難しいですが、このように考えてみてください。コンストラクタがある場合、デフォルトまたはそれ以外の場合、中括弧を超えて状態を伝播する唯一の方法は、ブールisValidを持つことです。(デフォルト値としてのnullとvコンストラクタの失敗)または、フィールドユーザーから取得したときに情報を提供しない例外をスローします。

コードは正直に言って、私は何千もの行コンストラクターを書き、必要なことを行います。オブジェクトの構築(つまり、2行のコンストラクター)でisValidを使用しているのを見つけましたが、何らかの理由で、静的なファクトリパターンに移行しています。メソッド呼び出しで多くのことができるように思えますが、それでもsync()の問題はありますが、デフォルトを「置換」することができます(より安全)

ここで必要なのは、何かに対してデフォルト値としてnullの問題に対処することだと思います。String one = new String( ""); メンバー変数として、コンストラクターに渡される文字列を割り当てる前にnullのチェックを行います。

Javaで行われた生の成層圏コンピュータサイエンスの量は非常に顕著です。

C ++などにはベンダーライブラリがあります。Javaは大規模なツールボックスであるため、大規模サーバーでそれらを超えることができます。静的イニシャライザブロックを調べてください。



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.