Перегрузка операторов в Java


181

Подскажите пожалуйста, возможно ли перегрузить операторы в Java? Если это используется где-нибудь в Java, не могли бы вы рассказать мне об этом.


Ответы:


235

Нет, Java не поддерживает пользовательскую перегрузку операторов. Единственный аспект Java, который приближается к «пользовательской» перегрузке операторов, - это обработка + для строк, которая приводит либо к конкатенации констант во время компиляции, либо к конкатенации во время выполнения с использованием StringBuilder / StringBuffer. Вы не можете определить свои собственные операторы, которые действуют таким же образом, хотя.

Для Java-подобных (и JVM основе) языка , который делает перегружать поддержки оператора, вы можете посмотреть на Котлин или Groovy . В качестве альтернативы, вам может повезти с плагином Java .


4
Вы говорите, что мы не можем создать оболочку в Java? Такие, как SmallInteger, как Integer?
huseyin tugrul buyukisik

3
@ tuğrulbüyükışık: Оболочки для всех существующих типов примитивов уже есть - но если вы хотите создать свой собственный новый тип обертки, вы не сможете заставить его вести себя так же, как другие, поскольку они имеют особую поддержку в языке.
Джон Скит

1
спасибо, я погуглил об этом и не смог найти. Я хотел знать, смогу ли я создать сложную переменную, состоящую из двух примитивов (double и int ---> хорошая точность + хороший диапазон)
huseyin tugrul buyukisik

40
@djaqeel: перегрузка оператора делает код менее читаемым при плохом использовании . При правильном использовании это может значительно улучшить читаемость IMO. Посмотрите на код, который используется BigIntegerв Java, затем посмотрите на подобный код, используя BigIntegerв C # операторы. Я не понимаю, как делегаты нарушают принципы ООП - вы должны быть более точными в своих возражениях. Я не знаю деталей того, почему Java-дизайнеры не включили различные функции, но я подозреваю, что есть смесь давления ресурсов и желания сделать язык маленьким и относительно простым.
Джон Скит

4
Я знаю, что уже поздно, но пример стоит тысячи аргументов. Учитывая , m0как Matrixи v0, v1, v2, v3, и , v4как Vectorс, просто сравнить , сколько времени требуется , чтобы вы правильно интерпретировать следующее математическое выражение 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

В дополнение ко всем людям, указавшим, что +перегружено для строк, -также перегружено как для операций с плавающей запятой, так и для целочисленных операций, как есть *и /.

[edit] %также перегружен для чисел с плавающей запятой, что может быть сюрпризом для тех, кто имеет C или C ++ фон.


21

Java не допускает перегрузки операторов. Предпочтительным подходом является определение метода в вашем классе для выполнения действия: a.add(b)вместо a + b. Вы можете увидеть краткую информацию о других битах, которые Java не учитывает в C-подобных языках, здесь: Функции, удаленные из C и C ++


2
Важным моментом является цель разработки сделать контекст исходных файлов Java независимым. Пытаясь читать очень большие (MLOC), макро-тяжелые программы на С имеют очень длинную кривую обучения. Сравнимая (или более крупная) Java-программа не сложнее, чем небольшая Java-программа. Как сказал Гослинг: «Язык, на котором могут работать программисты». [И любой, кто считает шаблонное многословие вредным, должен прочитать о разболтании в экспертном познании.]
Тим Виллискрофт,

2
Благодаря oracle ни одна из ссылок на java.sun.com не работает. Можете ли вы дать обновленную ссылку, если это возможно?
Сайед Акил Ашик

17

Вы не можете сделать это самостоятельно, поскольку Java не допускает перегрузки операторов.

Однако за одним исключением. + и + = перегружены для объектов String.


8
Есть много других примеров перегрузки операторов в Java. Например &, |и ^перегружены для booleanцелочисленных типов. И действительно, арифметические и реляционные операторы перегружены для различных числовых типов. (Конечно, семантика перегрузок намного ближе ...)
Стивен С

16

Как и многие другие ответили: Java не поддерживает пользовательскую перегрузку операторов.

Может быть, это не по теме, но я хочу прокомментировать некоторые вещи, которые я прочитал в некоторых ответах.

О читабельности.
Для сравнения:

  1. с = а + б
  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 смешиваются равенство и идентичность. Символ == (равенство) означает:
a. Равенство для примитивных типов.
б. Проверка идентичности для пользовательских типов, поэтому мы вынуждены использовать функцию equals () для равенства.
Но ... Какое это имеет отношение к перегрузке операторов?
Если язык допускает перегрузку оператора, пользователь может придать правильное значение оператору равенства.


Символ ==используется для равенства в Java, как в C и C ++. Это не имеет ничего общего с перегрузкой операторов.
Hot Licks

2
Оператор == в Java означает только равенство для примитивных типов. Для пользовательских типов означает идентичность. В C ++ семантика определяется пользователем, но должна сохранять встроенную семантику, равенство. Строка a = "привет"; Строка b = "привет"; логическое c = (a == b);
Фернандо Пелличчиони,

3
То, что вы сказали в своем первом комментарии, неверно. Правильно? Пожалуйста, скажите мне, как проверить равенство и идентичность на пользовательских типах в C. Вы правы, мой комментарий о равенстве - OT, но я уточнил это (см. «Дополнения»). Тот факт, что я не создал язык программирования, не означает, что я не могу критиковать существующий. Извините, если вы рассматривали критику как религиозную войну.
Фернандо Пелличчиони

1
Коротко говоря: Java - отстой.
Коля Иванков


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

Нет, вы не можете использовать скомпилированные Groovy JAR в Java таким же образом. Это все еще ошибка компилятора для Java.


1

В отличие от C ++, Java не поддерживает пользовательскую перегрузку операторов. Перегрузка выполняется внутри Java.

Мы можем взять +(плюс) например:

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

Здесь, плюс добавляет два целых числа и объединяет две строки. Таким образом, мы можем сказать, что Java поддерживает внутреннюю перегрузку операторов, но не определяется пользователем.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.