自从我开始使用Java以来,它一直非常恶心,因为它不支持从数字类型到布尔值的隐式转换,所以你不能做以下事情:
if (flags & 0x80) { ... }
相反,你必须经历这种疯狂:
if ((flags & 0x80) != 0) { ... }
与null和对象相同。我知道的其他类似C语言包括JavaScript允许它,所以我认为Java只是愚蠢的,但我刚刚发现C#是相同的(至少对于数字,不知道null /对象): http://msdn.microsoft.com/en-us/library/c8f5xwh7(VS.71).aspx
微软故意用C ++改变它,为什么呢?显然我错过了一些东西。为什么要改变(我认为是)世界上最自然的事情,让它更长久才能打字?它究竟出了什么问题?
答案 0 :(得分:37)
为清楚起见。它使以下错误完全违法:
int x = ...;
if (x = 0) // in C: assign 0 to x and always evaluate to false
.... // never executed
注意:大多数现代C / C ++编译器会在这种简单的模式上给出警告(但不是错误),但有许多变化可能。它可以爬上你。
答案 1 :(得分:32)
Java和C#都放弃了对布尔值的隐式转换,以减少程序员错误的可能性。
例如,许多程序员会不小心写:
if( x = 5 ) { ... }
而不是:
if( x == 5 ) { ... }
当然,这会导致完全不同的行为,因为第一个语句执行赋值(总是会产生true),而第二个语句执行比较。在过去,开发人员有时会反过来编写这样的任务以避免陷阱,因为:
if( 5 = x ) { ... } // doesn't compile.
现在,在C#中,你仍然可以为你自己的类型创建隐式转换运算符bool
- 虽然它很少是可取的,因为大多数开发人员并不期望它:
public class MyValue
{
public int Value { get; set; }
public static implicit operator bool( MyValue mb )
{
return mb.Value != 0;
}
}
MyValue x = new MyValue() { Value = 10; }
if( x ) { ... } // perfectly legal, compiler applies implicit conversion
答案 2 :(得分:10)
也许他们认为更加明确更符合强类型语言。
答案 3 :(得分:8)
你已经落后了。
它实际上是C不支持boolean
,因此if
(以及任何其他条件语句)实际上需要int
值,而不是boolean
。然后将0
的int值视为false,将任何其他值视为true
。
有些人实际上发现它有点含糊不清,因为这种行为会导致许多错误,正如其他人指出的那样。因此,Java设计者选择仅在条件语句中支持boolean
类型。当微软决定实施MS-Java(AKA C#)时,他们已经借用了这个设计原则。
如果你不喜欢它,你可以用各种没有这种限制的语言进行编程。
答案 4 :(得分:6)
将任何int值(例如(flags& 0x80))隐式转换为布尔值意味着语言定义从int值到布尔值的映射。 C做到了这一点,并造成了大量的混乱和程序员错误。没有充分的理由为什么零int值总是意味着真(或假)以及为什么你可能想把决定留给程序员的很多好理由。由于这些原因,大多数现代语言已经放弃了对布尔值的隐式转换。
如果每次进行一次测试时输入七个额外的字符构成“精神错乱”,那么你可能会处于错误的职业中。如果您经常在int中进行位测试,那么您可能需要考虑是否过早优化以节省内存。
答案 5 :(得分:3)
即使是最有经验的程序员也会遇到隐式转换为布尔值的问题。我很欣赏这个小小的特色。
答案 6 :(得分:2)
有些编程语言根本没有自动强制。例如,整数只能与另一个整数进行比较;赋值给非整数变量会导致错误。这是强类型语言的标志。
Java做任何强制都是对你的一种便利,打破了强类型模式。
将整个整数范围 - 或更大范围的浮点数 - 映射到两个布尔值上,充满了对“真实性”和“虚假性”的任意分配的分歧。
当您尝试自动将double转换为整数时,Java会将此标记为“精度损失”错误。通过类比,将数字转换为布尔值也会导致精度损失。相反,Java选择不在语法上支持它。