web-dev-qa-db-ja.com

Javaの三項/条件演算​​子(?:)を使用して、値を割り当てる代わりにメソッドを呼び出すことはできますか?

http://en.wikipedia.org/wiki/ ?: のようなページでは、三項/条件演算​​子?:が条件付き割り当てに使用されているようです。次のように、メソッド呼び出しに使用しようとしました。

(condition) ? doThis() : doThat();

どちらのメソッドもvoidを返します。 Javaは、ステートメントではないことを示しています。

だから、私は条件付きメソッド呼び出しを行うことができないと思います...または私はできますか?

28
Voldemort

この場合、三項演算子をメソッドのように考えてください。 _a ? b : c_と言うことは、(検討している意図と目的については、lasseespeholtのコメントを参照してください)擬似コードメソッドを呼び出すことと同じです。

_ternary(a, b, c)
    if a
        return b
    else
        return c
_

だから人々は_x = a ? b : c_のようなことを言うことができます。基本的にはx = ternary(a, b, c)と言うようなものです。 _(condition) ? doThis() : doThat()_と言うと、事実上次のようになります。

_if condition
    return doThis()
else
    return doThat()
_

メソッドをそれらが返すものに置き換えようとするとどうなるか見てください

_ if condition
    return ???
 else
    return ???
_

それを考えることすら意味がありません。 doThis()doThat()は何も返しません。これは、voidがインスタンス化可能な型ではないため、ternaryメソッドも何も返さないためです。 、したがってJavaはステートメントをどう処理するかわからず、文句を言います。

これを回避する方法はいくつかありますが、それらはすべて悪い習慣です(戻り値を持つようにメソッドを変更できますが、返されるものには何もしません。メソッドを呼び出してnullを返す新しいメソッドを作成できます。 。)。この場合、ifステートメントを使用する方がはるかに優れています。

[〜#〜] edit [〜#〜]さらに、さらに大きな問題があります。値を返していたとしても、Javaは_a ? b : c_をステートメントとは見なしません。

22
Jodaka

三項演算子は単純にシンタックスシュガーです。
コードの読み取り/書き込みは簡単になりますが、実際の機能は追加されません。
その主な用途は、コードの数行を1行に圧縮することであり、いくつかの条件に基づいてわずかに異なる文字列を作成するときに非常に役立ちました。

例えば。

_Collection<?> col = ...
System.out.println("There " + (col.size()==1 ? "is" : "are") + " "
     + col.size() + " " + (col.size()==1 ? "element" : "elements")
     + " in the collection");
_

の代わりに

_Collection<?> col = ...
String message = "There ";
if(col.size()==1)
    message += "is";
else
    message += "are";
message += " "+col.size()
if(col.size()==1)
    message += " element";
else
    message += " elements";
message += " in the collection";
System.out.println(message);
_

ご覧のとおり、コードが簡略化されています。
(注:2番目の例では、文字列の連結の代わりにStringBuilderを使用することをお勧めします)

ただし、_(condition) ? doThis() : doThat();_(戻り値なし)はif(condition) doThis(); else doThat();と同じ意味であるため、機能を追加せずに同じものを記述する方法は2つあります。それは物事を複雑にするだけです:

  • プログラマー向け:コードが統一されていない
  • 三項演算子の実装の場合:voidメソッドもサポートする必要があります

したがって、Noの場合、条件付きメソッドの呼び出しに三項演算を使用することはできません。代わりにif-elseを使用してください:

_if(condition)
    doThis();
else
    doThat(); 
_
2
neXus

三項(条件付き)演算子は値を返します。そうでない場合、それらを演算子の一部として使用することはできません(値を取得する場合)。

それをよりよく理解するために、1つの単純な二項演算子_+_について考えてみましょう。これは次のように機能します。

_<eval1> + <eval2>  -->  <value>
_

2つの評価可能なパーツが必要で、もう1つを返します。入力した場合

_doThis() + doThat();
_

あるいは

_gimmeAValue = doThis() + doThat();
_

doThis()doThat()も何も評価しないため、失敗します(voidを「返す」)。もちろん、_<eval1>_と_<eval2>_の両方が、_+_演算子がそれらを処理して何らかのタイプの値を返すことができるように、何らかの「互換性のある」タイプである必要があります。

次に、三項演算子を見てみましょう。

_<evalBoolean> ? <eval1> : <eval2>  -->  <value>
_

3つの評価可能な部分を取り、値を返します。

最初の評価可能な部分は、コンパイラーがブール値として理解できる(キャストできる)必要があります。これは、他の2つの評価可能なパーツのどちらを返却する必要があるかを決定するために使用されます。

他の2つの評価可能な部分は、まあ...評価可能でなければなりません。何かに。ある種の。

言い換えると、三項条件演算子は、コードの分岐としてではなく、何かを返すことを目的としています。このように使用されます:

_gimmeAValue = testMe() ? returnThis() : returnThat();
_
1
J.A.I.L.