Java中的运算符重载


Answers:


234

不,Java不支持用户定义的运算符重载。Java唯一接近“自定义”运算符重载的方面是对字符串的+处理,这将导致常量的编译时串联或使用StringBuilder / StringBuffer的执行时串联。但是,您无法定义自己的操作符,它们的操作方式相同。

对于确实支持运算符重载的类似Java(和基于JVM)的语言,您可以查看KotlinGroovy。另外,您可能会发现Java编译器插件解决方案很幸运。


4
您是说我们不能在Java中创建包装器吗?如SmallInteger之类的Integer?
huseyin tugrul buyukisik 2012年

3
@tuğrulbüyükışık:已经存在所有现有原始类型的包装器-但是如果您想创建自己的新包装器类型,则无法使其表现得与其他包装器一样,因为它们在语言方面有特定的支持。
乔恩·斯基特

1
谢谢,我用谷歌搜索,找不到。我想知道我是否可以制作一个由两个基元组成的复杂变量(一个双精度整数和一个int --->精度高+范围广)
huseyin tugrul buyukisik 2012年

40
@djaqeel:运算符重载使代码使用不当时会降低可读性。如果使用得当,它可以大大提高IMO的可读性。查看BigIntegerJava 中使用的代码,然后查看BigIntegerC#中使用运算符的类似代码。我看不到代表如何违反OOP原则-与反对相比,您需要更加精确。我不知道为什么Java设计人员不包括各种功能的细节,但是我怀疑资源压力和保持语言较小且相对简单的愿望混合在一起。
乔恩·斯基特

4
我知道这很晚了,但是一个例子值得一千个论点。鉴于m0作为Matrixv0v1v2v3,和v4VectorS,简单地比较需要多长时间你正确地理解下面的数学表达式m0.transpose().mult(v0.add(v1.mult(v2)).cross(v3)).sub(v4);。如果已包含对运算符重载的支持,则可以将其写为m0.transpose() * (v0 + v1 * v2).cross(v3) - v4;
code_dredd

38

Java中将运算符重载用于String类型的串联:

String concat = "one" + "two";

但是,您不能定义自己的运算符重载。


26

除了所有人指出的那样,+对于Strings -重载外,对于浮点和整数操作也是如此,并且对*and也是如此/

[edit] %对于浮点数也很重载,这对于具有C或C ++背景的用户可能会有些惊讶。


20

Java不允许运算符重载。首选方法是在类上定义一个方法来执行操作:a.add(b)而不是a + b。您可以在此处查看从类似C的语言中遗漏的Java其他部分的摘要:从C和C ++中删除的功能


2
重要的是使Java源文件与上下文无关的设计目标。尝试读取很大的(MLOC)宏繁重的C程序的学习曲线很长。可比(或更大)的Java程序不比小型Java程序更容易使用。正如Gosling所说:一种供蓝领程序员使用的语言。[任何认为样板冗长有害的人都应阅读有关专家认知中的分块的知识。]
Tim Williscroft 2011年

2
多亏了oracle,java.sun.com链接均无法正常工作。如果可以,请提供更新的链接吗?
Syed Aqeel Ashiq

17

您不能自己执行此操作,因为Java不允许运算符重载。

但是有一个例外。++ =对于String对象是重载的。


8
Java中还有许多其他的运算符重载示例。例如&|^boolean整数类型和重载类型。实际上,算术和关系运算符对于各种数字类型都是重载的。(当然,重载的语义更接近了……)
Stephen C

16

正如许多其他人回答的那样:Java不支持用户定义的运算符重载。

也许这是题外话,但我想对我在某些答案中读到的一些东西发表评论。

关于可读性。
比较:

  1. c = a + b
  2. c = a.add(b)

再看一次!
哪一个更具可读性?

允许创建用户定义类型的编程语言应允许它们以与内置类型(或原始类型)相同的方式运行。

因此,Java打破了通用编程的基本原理:
我们应该能够将内置类型的对象与用户定义类型的对象互换。
(您可能想知道:“他说的是'内置对象'吗?”。是的,请参见此处。)

关于字符串串联:

数学家使用符号+进行集合的交换运算。
因此我们可以确定a + b = b + a。
字符串连接(在大多数编程语言中)不遵守这种常见的数学符号。

a := "hello";
b := "world";
c := (a + b = b + a);

或使用Java:

String a = "hello";
String b = "world";
boolean c = (a + b).equals(b + a);

附加:
请注意在Java中如何混淆平等和身份。的==(平等)符号的装置:
一个。原始类型的相等性。
b。用户定义类型的身份检查,因此,我们被迫使用equals()函数实现相等性。
但是...这与运算符重载有什么关系?
如果语言允许运算符重载,则用户可以为相等运算符赋予适当的含义。


==与C和C ++一样,该符号在Java中用于相等性。这与操作符重载无关。
热门点击14-10-11

2
在Java中,operator ==仅表示基本类型的相等。对于用户定义的类型,表示身份。在C ++中,语义是由用户定义的,但应保留内置的语义,即相等性。字符串a =“ hello”; 字符串b =“ hello”; 布尔值c =(a == b);
Fernando Pelliccioni 2014年

3
因此,您在第一句话中所说的是错误的。对?请告诉我如何在C语言中的用户定义类型上测试相等性和同一性。您是对的,我对相等性的评论是OT,但我对此做了澄清(请参阅“附加说明”)。我没有创建一种编程语言这一事实​​并不意味着我不能批评一种现有的编程语言。对不起,如果您将批评视为宗教战争。
Fernando Pelliccioni 2014年

1
简单地说:java很烂。
Kolya Ivankov


6

只需将Xtend与Java代码一起使用即可。它支持运算符重载:

    package com.example;

@SuppressWarnings("all")
public class Test {
  protected int wrapped;

  public Test(final int value) {
    this.wrapped = value;
  }

  public int operator_plus(final Test e2) {
    return (this.wrapped + e2.wrapped);
  }
}

package com.example

class Test2 {

    new() {
        val t1 = new Test(3)
        val t2 = new Test(5)
        val t3 = t1 + t2
    }

}

在官方网站上,列出了为每个操作员实施的方法!


5

或者,您可以制作Java Groovy并仅重载这些功能即可实现所需的功能

//plus() => for the + operator
//multiply() => for the * operator
//leftShift() = for the << operator
// ... and so on ...

class Fish {
    def leftShift(Fish fish) {
        print "You just << (left shifted) some fish "
    }
}


def fish = new Fish()
def fish2 = new Fish()

fish << fish2

谁不想成为/使用常规?:D

不,您不能以相同的方式在Java中使用已编译的Groovy JAR。它仍然是Java的编译器错误。


1

与C ++不同,Java不支持用户定义的运算符重载。重载是在Java内部完成的。

我们可以+举(加)为例:

int a = 2 + 4;
string = "hello" + "world";

在这里,加号加上两个整数,并连接两个字符串。因此,可以说Java支持内部运算符重载,但不支持用户定义。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.