是否可以在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上的语法令牌,删除此令牌”和“其他无法解决的问题”等。
我做错了什么?
答案 0 :(得分:17)
是的,您可以使用单个语句跟随if
语句而不使用花括号(但您真的想要吗?),但您的问题更加微妙。尝试更改:
if (x=y)
为:
if (x==y)
某些语言(例如PHP)将任何非零值视为true,将零(或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()
编译没有错误。
编辑:但我认为我们已经建立了(虽然这是一个有趣的潜入晦涩的边缘情况),无论你想做什么,你都没有正确地做到这一点。那么你实际试图做什么?
答案 1 :(得分: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
语句中跳过使用花括号。它可能导致错误,例如向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
语句测试的结果如何,都将执行第二个语句if
。如果你开始使用花括号,你就可以避免这个问题。
if (x == y) {
z = y * x;
w = x * y - 5; // this is obviously inside the if statement now
}
答案 2 :(得分:3)
请务必咨询Code Conventions for the JavaTM Programming Language:
具体来说,请参阅Chapter 7, Section 4:
注意: if语句始终使用大括号{}。避免以下情况 容易出错的形式:
if (condition) //AVOID! THIS OMITS THE BRACES {}! statement;
答案 3 :(得分:3)
如果你想要一个单行,如果是表达式,你可以使用三元运算符
final int myVal = predicate ? consequent : alternative;
与
大致相同 final int myVal;
if(predicate)
myVal = consequent;
else
myVal = alternative;
答案 4 :(得分: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认识到这种情况并且告诉你(To slomely引用Inigo Montoya)“我认为这并不意味着你的意思”。
次要问题,Java是强类型的。即使它可能允许像你所说的语法,在这个if语句之后,它必须具有realOther的绝对最终类型。你的if语句会完全破坏java的大脑,因为它不知道是否应该将realOther视为矩形或正方形。
假设矩形有setWidth和setHeight方法(而square只有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);
}
换句话说,您应该使用相关对象的方式是尽可能长时间地将它们保留为更抽象的对象,只需在需要调用该对象上的方法时使用特定对象。 / p>
如果你编码正确,你几乎总能使用更抽象的,很少使用特定的。使用square和rect,这并不明显,square / rect是一个非常草率的问题,并且用作OO编程必须做出的一些艰难决定的例子,但它确实几乎一直在运行 - 我很少得演员......
答案 5 :(得分:2)
这是可能的(除了@Sean指出的错字/错误),但根据您遵循的代码指南,它被视为不良形式。
我通常遵循的代码指南(无论是在工作中还是在我决定的私有项目中)都禁止没有块的单个语句(即每个if / while / for需要一个块)。
答案 6 :(得分: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();
答案 7 :(得分:0)
是的,但你需要在if-else之间保留半冒号,如下所示:
if (true) System.out.println("true"); else System.out.println("false");
另外,请确保将比较运算符修改为==
。
答案 8 :(得分:0)
仅仅因为你可以做某事并不意味着你应该做。
考虑添加日志记录时会发生什么:
if (x==y)
z=x*y;
else
System.out.println("Values weren't equal);
z=y-x;
惊喜! “z”永远不会等于x * y。虽然您可能认为将括号括起来会使您的代码更具可读性,但这会使安全性降低。我只是这样说,因为我不得不解决大量具有同样缺陷的代码。
答案 9 :(得分:0)
我总是使用大括号,因为有些语言允许使用大括号,而有些语言不允许,我永远不能保持直接。也许我太老了,或者我知道的语言太多了。
答案 10 :(得分:0)
我必须同意Bill K ... “你不能在if语句中说”Square realOther“,因为你在单行代码的范围内声明它,它会在if语句的末尾消失。”
考虑将realOther预先定义为Object,然后简单地将realOther与=(Square)other分配; / =(矩形)其他;
但是,地方性是你的问题。
答案 11 :(得分:0)
获取代码以使用大括号,然后将其删除。如果你正在学习新东西,你应该一次做一件事。
答案 12 :(得分:0)
如果是else else语句,你也可以做一行:
z = (x == y)? x*y : y-z;