从c++到Java,一个显而易见的未回答的问题是为什么Java没有包含操作符重载?

复合物不是a b c吗?A = b + c;比复合物a, b, c简单得多;A = b.add(c);?

是否有一个已知的原因,不允许操作符重载的有效参数?理由是随意的,还是被时间消磨了?


当前回答

Groovy具有操作符重载,并且运行在JVM中。如果您不介意性能损失(每天都在减小)。它是基于方法名自动生成的。例如,'+'调用'plus(参数)'方法。

其他回答

有时,操作符重载、友类和多重继承会很好。

然而,我仍然认为这是一个很好的决定。如果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没有操作符重载,这里有一些你可以考虑的替代方案:

使用另一种语言。Groovy、Scala和Kotlin都有操作符重载,它们都是基于Java的。 使用Java -oo,这是一个在Java中支持操作符重载的插件。注意,它不是平台独立的。此外,它有许多问题,并且与Java的最新版本(即Java 10)不兼容。(StackOverflow原始源码) 使用JNI、Java本机接口或替代方案。这允许您编写在Java中使用的C或c++方法。当然,这也不是平台独立的。

如果有人知道其他人,请评论,我会把它添加到这个列表中。

Java不允许操作符重载,因为它的创建者没有添加将不同含义与同一个操作符关联起来的功能。他们只是想通过在整个编程语言中保持运算符统一的含义来简化事情。

重载操作符会使事情变得混乱,并为新程序员创造了陡峭的学习曲线。他们只是把运算符重载从教学大纲中去掉了。

你可能真的会搬起石头砸自己的脚。这就像指针一样,人们会犯愚蠢的错误,所以我们决定把剪刀拿走。

至少我认为这是原因。 反正我是站在你这边的。:)