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)是 的值y,而不是truefalse

您可以通过这个简单的示例看到这一点:

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

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

第一条语句将导致编译失败,因为1无法转换为布尔值。

编辑:我对您更新示例的猜测(您应该将其放入问题而不是作为新答案)是您realOther在这些语句中分配它之后尝试访问。这将不起作用,因为范围realOther仅限于if/else语句。您需要将声明移到语句realOther上方if(在这种情况下将无用),或者在if语句中添加更多逻辑):

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另一件要提到的事情是,许多人认为在语句中跳过使用花括号是不好的做法。它可能会导致错误,例如在ifelse代码块的主体中​​添加另一条语句。这是一种可能很难弄清楚的错误类型。

使用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的结果如何,都会执行第二条语句。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

请始终查阅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 回答
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 语句将完全打破 java 的大脑,因为它不知道 realOther 应该被视为矩形还是正方形。

假设矩形有一个 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 回答
2

这是可能的(除了@Sean 指出的错字/错误),但根据您遵循的代码指南,它被认为是错误的形式。

我通常遵循的代码指南(无论是在工作中还是在我决定的私人项目中)都禁止没有块的单个语句(即每个 if/while/for 都需要一个块)。

于 2009-02-02T17:20:50.930 回答
2

你的代码是这样的吗?

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

//...

realOther.doSomething();

问题是在 Java 中,不像 PHP,在语句realOther之外不存在。if是什么类型的other?是Object吗?如果是这样,Square 和 Rectangle 是否有共同的基类或接口?(Shape也许?)如果是这样,你应该做更多这样的事情:

Shape realOther = null;
if(other instanceof Shape)
  realOther = other;

//...

if(realOther != null)
  realOther.doSomething();
于 2009-02-02T18:25:11.393 回答
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 回答
0

我必须同意 Bill K...“你不能在 if 语句中说‘Square realOther’,因为你在单行代码的范围内声明它,它会在 if 语句的末尾消失。”

考虑预先将 realOther 定义为 Object,然后简单地将 realOther 与 = (Square) other; / =(矩形)其他;

不过,地方性是你的问题。

于 2009-02-02T18:15:06.580 回答
0

让您的代码使用大括号,然后删除它们。如果你正在学习新的东西,你应该一次做一件事。

于 2009-02-02T19:41:18.590 回答
0

你也可以这样写一行 if then else 语句:

z = (x == y)? x*y : y-z;
于 2012-05-22T19:51:35.340 回答