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

时间:2010-06-01 17:06:53

标签: c# java boolean type-conversion

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

7 个答案:

答案 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做任何强制都是对你的一种便利,打破了强类型模式。

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

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

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