从c++到Java,一个显而易见的未回答的问题是为什么Java没有包含操作符重载?
复合物不是a b c吗?A = b + c;比复合物a, b, c简单得多;A = b.add(c);?
是否有一个已知的原因,不允许操作符重载的有效参数?理由是随意的,还是被时间消磨了?
从c++到Java,一个显而易见的未回答的问题是为什么Java没有包含操作符重载?
复合物不是a b c吗?A = b + c;比复合物a, b, c简单得多;A = b.add(c);?
是否有一个已知的原因,不允许操作符重载的有效参数?理由是随意的,还是被时间消磨了?
当前回答
Saying that operator overloading leads to logical errors of type that operator does not match the operation logic, it's like saying nothing. The same type of error will occur if function name is inappropriate for operation logic - so what's the solution: drop the ability of function usage!? This is a comical answer - "Inappropriate for operation logic", every parameter name, every class, function or whatever can be logicly inappropriate. I think that this option should be available in respectable programing language, and those that think that it's unsafe - hey no bothy says you have to use it. Lets take the C#. They drooped the pointers but hey - there is 'unsafe code' statement - program as you like on your own risk.
其他回答
有时,操作符重载、友类和多重继承会很好。
然而,我仍然认为这是一个很好的决定。如果Java有运算符重载,那么如果不查看源代码,我们就永远无法确定运算符的含义。目前还没有必要。而且我认为你使用方法而不是操作符重载的例子也是相当可读的。如果你想让事情更清楚,你总是可以在烦人的语句之上添加注释。
// a = b + c
Complex a, b, c; a = b.add(c);
假设您想要覆盖a所引用的对象的先前值,那么必须调用成员函数。
Complex a, b, c;
// ...
a = b.add(c);
在c++中,这个表达式告诉编译器在堆栈上创建三(3)个对象,执行加法,并将结果值从临时对象复制到现有对象a中。
然而,在Java中,operator=并不为引用类型执行值复制,用户只能创建新的引用类型,而不能创建值类型。因此,对于名为Complex的用户定义类型,赋值意味着将引用复制到现有值。
考虑:
b.set(1, 0); // initialize to real number '1'
a = b;
b.set(2, 0);
assert( !a.equals(b) ); // this assertion will fail
在c++中,这将复制值,因此比较结果将是不相等的。在Java中,operator=执行引用复制,因此a和b现在引用相同的值。结果,比较将产生'equal',因为对象的比较结果将等于自身。
复制和引用之间的差异只会增加操作符重载的混乱。正如@Sebastian所提到的,Java和c#都必须分别处理值和引用相等——operator+可能会处理值和对象,但operator=已经被实现来处理引用。
在c++中,一次只能处理一种比较,这样就不会那么令人困惑。例如,在Complex上,operator=和operator==都处理值——分别复制值和比较值。
有人说Java中的操作符重载会导致混淆。这些人是否曾经停下来查看一些Java代码进行一些基本的数学运算,比如使用BigDecimal将财务值按百分比增加?.... 这种做法的冗长本身就证明了混淆视听。具有讽刺意味的是,向Java中添加运算符重载将允许我们创建自己的Currency类,这将使此类数学代码优雅而简单(不那么混乱)。
Groovy具有操作符重载,并且运行在JVM中。如果您不介意性能损失(每天都在减小)。它是基于方法名自动生成的。例如,'+'调用'plus(参数)'方法。
Saying that operator overloading leads to logical errors of type that operator does not match the operation logic, it's like saying nothing. The same type of error will occur if function name is inappropriate for operation logic - so what's the solution: drop the ability of function usage!? This is a comical answer - "Inappropriate for operation logic", every parameter name, every class, function or whatever can be logicly inappropriate. I think that this option should be available in respectable programing language, and those that think that it's unsafe - hey no bothy says you have to use it. Lets take the C#. They drooped the pointers but hey - there is 'unsafe code' statement - program as you like on your own risk.