为什么Java和C#没有隐式转换为布尔值?

自从我开始使用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 ++改变它,为什么呢? 显然我错过了一些东西。 为什么要改变(我认为是)世界上最自然的事情,让它更长久才能打字? 它到底有什么问题?

为清楚起见。 它使以下错误完全违法:

 int x = ...; if (x = 0) // in C: assign 0 to x and always evaluate to false .... // never executed 

注意:大多数现代C / C ++编译器会在这种简单的模式上给出警告(但不是错误),但可能存在许多变化。 它可以爬上你。

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 

也许他们认为更加明确更符合强类型语言。

你已经落后了。
它实际上是C不支持boolean ,所以if (和任何其他条件语句)实际上需要一个int值,而不是boolean 。 然后将int值0视为false,将任何其他值视为true

有些人实际上发现它有点含糊不清,因为这种行为会导致许多错误,正如其他人所指出的那样。 因此,Java设计者选择在条件语句中仅支持boolean类型。 当微软决定实施MS-Java(AKA C#)时,他们借用了这个设计原则。

如果您不喜欢它,可以使用各种没有此限制的语言进行编程。

将任何int值(例如(flags&0x80))隐式转换为布尔值意味着语言定义从int值到布尔值的映射。 C做到了这一点,并造成了大量的混乱和程序员错误。 没有充分的理由为什么零int值总是意味着真(或假)以及为什么你可能想把决定留给程序员的很多好理由。 由于这些原因,大多数现代语言已经放弃了对布尔值的隐式转换。

如果每次进行一次测试时输入七个额外的字符构成“精神错乱”,那么你可能处于错误的职业。 如果你经常在int中进行位测试,你可能想要考虑是否过早优化以节省内存。

即使是最有经验的程序员也会遇到隐式转换为布尔值的问题。 我很欣赏这个小function。

有些编程语言根本没有自动强制。 例如,整数只能与另一个整数进行比较; 赋值给非整数变量会导致错误。 这是强类型语言的标志。

Java做任何强制都是对你的一种便利,打破了强类型模型。

将整个整数范围 – 或更大范围的浮点数 – 映射到两个布尔值上充满了对“真实性”和“虚假性”的任意分配的不同意见。

  • 什么价值观映射到虚假和真实? 如果您是C,则只有零映射为false,所有其他值都为true。 如果你是bash shell,那就相反了。
  • 如何映射负值?

当您尝试自动将double转换为整数时,Java会将此标记为“精度损失”错误。 通过类比,将数字转换为布尔值也会导致精度损失。 相反,Java选择不在语法上支持它。