7

Java で中括弧なしで IF ステートメントを使用することは可能ですか。

if (x == y)
  z = x * y;
else
  z = y - x;

PHPでは可能ですが、何か間違っているかどうかはわかりません。

明確化:これが私が使用している私の実際のコードです:

if (other instanceof Square)
    Square realOther = (Square) other;
else
    Rectangle realOther = (Rectangle) other;

しかし、「 realOther の構文トークン、このトークンを削除してください」や「 realOther を解決できません」などのエラーが発生しました。

私は何を間違っていますか?

4

13 に答える 13

18

はい、if中かっこを使用せずに単一のステートメントをステートメントの後に続けることができます (しかし、本当にしたいですか?) が、問題はより微妙です。変更してみてください:

if (x=y)

に:

if (x==y)

一部の言語 (たとえば、PHP など) は、ゼロ以外の値を true として扱い、ゼロ (またはNULL, null,nilなど) を として扱いfalseます。そのため、条件付きの代入演算は機能します。Java では、条件ステートメント内でブール式 (ブール値を返す、またはブール値に評価される式) のみが許可されます。の結果がまたはではなく(x=y)の値であるため、このエラーが表示されます。ytruefalse

次の簡単な例で、実際の動作を確認できます。

if (1)
    System.out.println("It's true");

if (true)
    System.out.println("It's true");

1最初のステートメントはブール値に変換できないため、コンパイルが失敗します。

編集:更新された例(新しい回答としてではなく、質問に入れるべきだった)についての私の推測はrealOther、それらのステートメントで割り当てた後にアクセスしようとしているということです。の範囲が/ステートメントrealOtherに限定されているため、これは機能しません。の宣言をステートメントの上に移動するか(この場合は役に立たない)、ステートメントにロジックを追加する必要があります)。ifelserealOtherifif

if (other instanceof Square)
    ((Square) other).doSomething();
else
    ((Rectangle) other).doSomethingElse();

さらに支援するには、実際のコードをもっと見る必要があります。

編集:次のコードを使用すると、表示されているのと同じエラーが発生します(でコンパイルgcj):

public class Test {
    public static void Main(String [] args) {
        Object other = new Square();

        if (other instanceof Square)
            Square realOther = (Square) other;
        else
            Rectangle realOther = (Rectangle) other;

        return;
    }
}

class Rectangle {
    public Rectangle() { }
    public void doSomethingElse() {
        System.out.println("Something");
    }
}

class Square {
    public Square() { }
    public void doSomething() {
        System.out.println("Something");
    }
}

ifその/ステートメントに中括弧を追加elseすると、エラーが未使用の変数に関する警告に減少することに注意してください。私たち自身のmmyers は次のように指摘しています。

http://java.sun.com/docs/books/jls/third_edition/html/statements.html には、「すべてのローカル変数宣言ステートメントはすぐにブロックに含まれる」と書かれています。ステートメント内のもの ifは中かっこで囲まれていないため、ブロックには含まれていません。

私の他の例にも注意してください:

((Square) other).doSomething()

エラーなしでコンパイルされます。

編集:しかし、私たちは(これはあいまいなエッジケースへの興味深い飛び込みですが)何をしようとしても、それを正しく行っていないことを確立したと思います. それで、あなたは実際に何をしようとしていますか?

于 2009-02-02T17:14:51.613 に答える
4

次のコード有効です。

int x = 5;
int y = 2;
int z = 0;

if (x == y)
  z = x * y;
else
  z = y - x;

Sean Bright が述べたように、問題は非ブール式をテストしようとしていることです。句==では、演算子の代わりに演算子を使用する必要があり=ます。if

if-then-else言及すべきもう 1 つのことは、多くの場合、ステートメントで中括弧の使用をスキップすることは悪い習慣であると考えられていることです。ifまたはelseコード ブロックの本体に別のステートメントを追加するなど、後でエラーが発生する可能性があります。これは、理解するのが面倒なタイプのバグです。

これはif-elseステートメントを使用する場合には実際には問題ではありません。Java はこれを構文エラー (else先行するステートメントのないステートメントif) としてキャッチするからです。ただし、次のifステートメントを考慮してください。

if (x == y)
  z = y * x;

ここで、後でさらに多くのことを行う必要があるとしますx == y。エラーに気付かずに次のことを簡単に実行できます。

if (x == y)
  z = y * x;
  w = x * y - 5;

もちろん、ステートメント テストw = x * y - 5の結果に関係なく、2 番目のステートメントが実行されます。if最初に中括弧があれば、この問題は回避できたはずです。

if (x == y) {
  z = y * x;
  w = x * y - 5; // this is obviously inside the if statement now
}
于 2009-02-02T17:19:55.160 に答える
3

編集:より明確にするために、これはあなたの問題です:

これ:

if (other instanceof Square)
    Square realOther = (Square) other;
else
    Rectangle realOther = (Rectangle) other;

これとまったく同じです:

if (other instanceof Square) {
    Square realOther = (Square) other;
} else {
    Rectangle realOther = (Rectangle) other;
}

realOther では何もしないことに注意してください。そこで定義しますが、その中かっこのセットにスコープが設定されているため、閉じ中かっこに到達するとすぐに破棄します。

中括弧を含めないことは役に立ちません。それが (if の後の) ステートメントであるという事実により、独立したコード ブロックになり、そのブロックが終了するとすぐに、「realOther」は破棄されます。

Java はこれが事実であることを認識し、(Inigo Montoya の言葉をずさんに引用すると)「それはあなたが考えていることを意味するとは思わない」と伝えます。

二次的な問題として、Java は厳密に型指定されています。あなたが言っているような構文を許可するかもしれませんが、このifステートメントの直後に、realOtherの絶対最終型が必要です。あなたのifステートメントは、realOtherが長方形または正方形として扱われることになっていたかどうかわからないため、Javaの脳を完全に壊します。

長方形に setWidth および setHeight メソッドがあるとします (正方形には setHeight しかありません)。この IF ステートメントの後、Java は setWidth を呼び出すことを許可する必要がありますか? Java はコンパイル時にこれらのことを認識している必要があります (そうでない場合、キャストは必要ありません)。

別の編集:

それを修正するには、これを使用します。

// class Rectangle extends Square
// Both implement setHeight, Rect also implements setWidth.
public void reSize(Square other, int h, int w) {
    other.setHeight(h);

    if (realOther instanceof Rectangle) {
        ((Rectangle)realOther).setWidth(w);
}

言い換えれば、関連するオブジェクトを操作する方法は、オブジェクトのメソッドを呼び出す必要がある場合にのみ特定のオブジェクトを使用して、それらをより抽象的なオブジェクトとしてできるだけ長く残しておくことです。

正しくコーディングすれば、ほとんどの場合、より抽象的なものを使用でき、具体的なものはほとんど使用できません。square と rect の場合、これは明らかではありません。square/rect はかなりずさんな問題であり、OO プログラミングで行う必要があるいくつかの難しい決定の例として使用されますが、実際にはほぼ常にうまくいきます。キャストする必要はほとんどありません...

于 2009-02-02T17:36:35.253 に答える
3

JavaTM プログラミング言語のコード規約を必ず参照してください。

具体的には、第 7 章、セクション 4を参照してください。

注: if ステートメントでは常に中かっこ {} を使用します。エラーが発生しやすい次の形式は避けてください。

if (condition) //AVOID! THIS OMITS THE BRACES {}!
    statement;
于 2009-02-02T17:25:18.643 に答える
3

それが式である場合にワンライナーが必要な場合は、三項演算子を使用できます

  final int myVal = predicate ? consequent : alternative;

これはほぼ同じです

  final int myVal;
  if(predicate)
    myVal = consequent;
  else
    myVal = alternative;
于 2009-02-02T17:26:19.173 に答える
2

それは可能ですが (@Sean が指摘したタイプミス/バグは別として)、従うコード ガイドラインによっては、それは悪い形式と見なされます。

私が通常従うコード ガイドライン (職場と私が決定したプライベート プロジェクトの両方) では、ブロックのない単一のステートメント (つまり、すべての if/while/for がブロックを必要とする) を禁止しています。

于 2009-02-02T17:20:50.930 に答える
0

次のように、1 行の if then else ステートメントを実行することもできます。

z = (x == y)? x*y : y-z;
于 2012-05-22T19:51:35.340 に答える
0

私は Bill K に同意する必要があります... 「if ステートメントで "Square realOther" と言うのは、その 1 行のコードの範囲内で宣言しているため、if ステートメントの最後で消えてしまうからです。」

事前に realOther をオブジェクトとして定義し、単純に realOther に = (Square) other; を割り当てることを検討してください。/ = (長方形) その他;

ただし、地域性はあなたの問題です。

于 2009-02-02T18:15:06.580 に答える
0

はい。ただし、次のように、if-else の間にセミコロンを入れる必要があります。

if (true) System.out.println("true"); else System.out.println("false");

また、比較演算子を に修正してください==

于 2009-02-02T17:18:11.623 に答える
0

何かができるからといって、そうしなければならないわけではありません。

ロギングを追加するとどうなるかを考えてみましょう。

if (x==y)
   z=x*y;
else
  System.out.println("Values weren't equal);
  z=y-x;

サプライズ!「z」が x * y と等しくなることはありません。括弧を外すとコードが読みやすくなると思うかもしれませんが、安全性が大幅に低下します。私がこれを言うのは、これと同じ欠陥を持つ大量のコードをトラブルシューティングしなければならなかったからです。

于 2009-02-02T17:23:56.930 に答える
0

中括弧を使用できる言語と許可しない言語があるため、私は常に中括弧を使用します。たぶん私は年を取りすぎているか、または多くの言語を知っているのかもしれません。

于 2009-02-02T17:30:45.107 に答える