java中的1行IF语句
Posted
技术标签:
【中文标题】java中的1行IF语句【英文标题】:1-line IF statements in java 【发布时间】:2010-10-04 23:27:03 【问题描述】:在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 无法解析”等错误。
我做错了什么?
【问题讨论】:
你知道多态性吗?不想刻薄,只是可以使用多态性代替我见过的大约 99% 的 instanceof 用法。你可能仍然在另外 1% 中,但我想看看你接下来用 realOther 做什么。 【参考方案1】:是的,您可以在 if
语句之后使用单个语句而不使用花括号(但您真的想要吗?),但您的问题更加微妙。尝试改变:
if (x=y)
到:
if (x==y)
某些语言(例如 PHP)将任何非零值视为真,将零(或 NULL
、null
、nil
等)视为false
,因此条件中的赋值操作有效。 Java 只允许在条件语句中使用布尔表达式(返回或评估为布尔值的表达式)。您看到此错误是因为(x=y)
的结果是y
的值,而不是true
或false
。
您可以通过这个简单的示例看到这一点:
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()
编译没有错误。
编辑:但我认为我们已经确定(虽然这是对模糊边缘情况的有趣深入研究),无论您尝试做什么,您都没有正确执行。那么你实际上想做什么?
【讨论】:
其实你可以在if中使用=,你只需要使用它的结果作为一个布尔表达式,例如int i; if(i=1==1) loopForever();当然,这是非常糟糕的做法。 关于“Java 标准的某些部分”:java.sun.com/docs/books/jls/third_edition/html/statements.html 说:“每个局部变量声明语句都立即包含在一个块中。” for 语句中的那些没有大括号,因此它们不在一个块中。【参考方案2】:以下代码是合法的:
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
语句中跳过使用花括号是不好的做法。它可能会导致错误,例如在if
或else
代码块的主体中添加另一个语句。这种类型的 bug 可能很难弄清楚。
在使用if-else
语句时,这并不是真正的问题,因为Java 会将此作为语法错误(else
语句没有前面的if
)来捕获。但是,请考虑以下 if
声明:
if (x == y)
z = y * x;
现在,假设您稍后需要做更多的事情,如果x == y
。您可以轻松地执行以下操作而不会意识到错误。
if (x == y)
z = y * x;
w = x * y - 5;
当然,无论if
语句测试的结果如何,都会执行第二条语句w = x * y - 5
。如果你一开始就有花括号,你就可以避免这个问题。
if (x == y)
z = y * x;
w = x * y - 5; // this is obviously inside the if statement now
【讨论】:
【参考方案3】:请随时咨询Code Conventions for the JavaTM Programming Language:
具体见Chapter 7, Section 4:
注意: if 语句总是使用大括号 。避免以下情况 容易出错的形式:
if (condition) //AVOID! THIS OMITS THE BRACES ! statement;
【讨论】:
我个人讨厌这个禁令。我已经编码 9 年了,我从来没有见过因为省略括号而导致的问题,除非缩进不正确(在这种情况下,我看到有或没有括号都会出现问题) . 我认为这是真的,如果你遵循真正的 java 代码约定,它只需要多出一行,而且阅读起来非常好,这是最重要的事情之一。 我同意 Kip 的观点,从不认为这是一个问题,而且我发现没有大括号的情况下它更具可读性。没有“真正的”约定,有很多约定,通常由开始编写应用它们的任何给定代码库的开发人员定义。其中许多是宗教辩论的素材。【参考方案4】:如果你想要一个单行,如果那是一个表达式,你可以使用三元运算符
final int myVal = predicate ? consequent : alternative;
大致相同
final int myVal;
if(predicate)
myVal = consequent;
else
myVal = alternative;
【讨论】:
【参考方案5】:编辑:更清楚地说,这是你的问题:
这个:
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 编程中做出的一些艰难决定的示例,但它确实几乎一直都有效——我很少需要投射...
【讨论】:
【参考方案6】:这是可能的(除了@Sean 指出的错字/错误),但根据您遵循的代码指南,它被认为是错误的形式。
我通常遵循的代码指南(在工作中和我决定的私人项目中)禁止没有块的单个语句(即每个 if/while/for 都需要一个块)。
【讨论】:
【参考方案7】:你的代码是这样的吗?
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();
【讨论】:
【参考方案8】:是的,但你需要在 if-else 之间保留分号,如下所示:
if (true) System.out.println("true"); else System.out.println("false");
另外,请确保将比较运算符固定为 ==
。
【讨论】:
【参考方案9】:仅仅因为您可以做某事并不意味着您应该做某事。
考虑添加日志记录时会发生什么:
if (x==y)
z=x*y;
else
System.out.println("Values weren't equal);
z=y-x;
惊喜! “z”永远不会等于 x * y。虽然您可能认为省略括号会使您的代码更具可读性,但这会使其安全性大大降低。我之所以这么说,是因为我不得不对大量具有相同缺陷的代码进行故障排除。
【讨论】:
我从来没有见过有人犯过这个错误,如果语句是微不足道的并且缩进是正确的。绝不。这种禁止是对非问题的过度反应。 (好吧,我吐槽完了。) 这里也一样。这与参数或局部变量中的“final”、方法中的多个“return”、换行符上的花括号……以及关于某些人认为“正确”编码风格的各种其他宗教辩论。【参考方案10】:我总是使用大括号,因为有些语言允许使用大括号,有些则不允许,而且我永远无法保持正确。可能是我太老了,也可能是我懂的语言太多了。
【讨论】:
【参考方案11】:我必须同意 Bill K... “您不能在 if 语句中说“Square realOther”,因为您在该单行代码的范围内声明它,它会在 if 语句的末尾消失。”
考虑预先将 realOther 定义为 Object,然后简单地将 realOther 与 = (Square) other; / =(矩形)其他;
不过,地点是你的问题。
【讨论】:
【参考方案12】:让您的代码使用大括号,然后删除它们。如果你正在学习新的东西,你应该一次做一件事。
【讨论】:
【参考方案13】:你也可以这样写一行 if then else 语句:
z = (x == y)? x*y : y-z;
【讨论】:
以上是关于java中的1行IF语句的主要内容,如果未能解决你的问题,请参考以下文章