web-dev-qa-db-ja.com

Java割り当てのない3項

代入やアセスメントを偽造せずにJava三項演算を実行する方法はありますか?

たくさんのif/then/elsesを実行するときに簡潔な3進コードがどのように見えるかが好きです。

ブール代数ステートメントに基づいて、2つのvoid関数のいずれかを呼び出せるようにしたいと思っています。

何かのようなもの:

(bool1 && bool2) ? voidFunc1() : voidFunc2();

私の関数は戻り値の型voidなので、これを割り当てで偽造して機能させる方法があれば、それで大丈夫です...それを行う方法を知りたいのですが:)

24
James Oravec

いいえ、それはできません。 仕様はそう言っています

条件演算子には3つのオペランド式があります。 ? 1番目と2番目の式の間に表示され、:は2番目と3番目の式の間に表示されます。

最初の式はブール型またはブール型である必要があります。そうでない場合、コンパイル時エラーが発生します。

2番目または3番目のオペランド式がvoidの呼び出しであるのはコンパイル時エラーですメソッド。

[編集]

リフレクションについて質問されたので、ここに解決策があります。私はこれをお勧めしません。あなたが尋ねたという理由だけでそれを投稿します。

public class MyCall
{

    public void a(){System.out.println("a");}
    public void b(){System.out.println("b");}

    public static void main(String... args)
    {
        new MyCall().go();
    }

    public void go()
    {
        Class<? extends MyCall> class1 = this.getClass();
        Method aMethod = class1.getMethod("b", null);
        Method bMethod = class1.getMethod("a", null);
        Object fake = false ? aMethod.invoke(this, null) : bMethod.invoke(this, null);
        Object fake2 = true ? aMethod.invoke(this, null) : bMethod.invoke(this, null);
    }
}

一日の終わりに、簡潔であることがコードの可読性を向上させるかどうかを自問する必要があります(for-eachループを考えてください)。これらのソリューションはいずれも、コードの可読性を向上させるものではありません。もし私があなたなら、私はむしろこれで行きたいです。

if(condition)
    a();
else
    b();

私は実際にはforループに1行しかない場合でも中括弧を含めていますが、鮮明なコードを求めているので、上記のスニペットで十分です。

21
Deepak Bala

いいえ、このようにすることはできません。

より多くのステートメントを作成したくない場合は、このスタイルを選択できます。

if(bool1 && bool2) voidFunc1(); else voidFunc2();

三項演算子では、オペランドは非void式である必要があります。つまり、実際の値を生成する必要があります。

8
Ajay S

あなたが本当に-本当にターナニー操作を使いたいのなら、1つのハックがあります。しかし、これは非常に悪いコードであり、言語の能力を示すことだけを目的としています。このコードを本番環境に導入したり、友達に見せたりすることは決してお勧めしません。

int dummy = (bool1 && bool2) ? new Object(){
        public int hashCode() {
            yourFunction1();
            // ...
            yourFunctionN();
            return 0;
        };
    }.hashCode() : new Object(){
        public int hashCode() {
            yourAnotherFunction1();
            // ...
            yourAnotherFunctionN();
            return 0;
        };
    }.hashCode();
2
Alex Stamper

代入を行わずにJava三項演算を実行する方法、または代入を偽造する方法はありますか?

OK、それであなたがこのようなステートメントを書くとき:

    (bool1 && bool2) ? voidFunc1() : voidFunc2();

コードには2つの明確な問題があります。

  1. 条件式の2番目と3番目のオペランド1 voidメソッドを呼び出すことはできません。参照: JLS 15.25

  2. 式はステートメントではありません。ただし、代入式ORメソッド呼び出しORオブジェクトの作成です。参照: JLS 14.8

実際、これらの問題の2番目はsyntaxエラーであり、主流のJavaコンパイラーがそれを報告することを期待します最初の問題の代わりに。最初の問題は、次のようなことをした場合にのみ明らかになります。

    SomeType dummy = (bool1 && bool2) ? voidFunc1() : voidFunc2();

または

    gobble((bool1 && bool2) ? voidFunc1() : voidFunc2());

ここで、gobbleは、引数の値を「消費」する以外は何もしないメソッドです。

AFAIK、元の表現が受け入れられるコンテキストはありません。


1-「条件式」は、Java言語仕様でこの構造に使用される主要な用語です。Oracleでは「三項条件演算子」と呼ばれますJavaチュートリアル。

1
Stephen C