Перевантаження оператора в 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
дякую, я погуглився про це і не міг знайти. Мені хотілося знати, чи можу я зробити складну змінну, складену з двох примітивів (подвійний та інт ---> добра точність + хороший діапазон)
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

На додаток до всіх людей, які зазначають, що +перевантажений для Strings, -також перевантажений як операціями з плаваючою точкою, так і цілими операціями, як є, так *і /.

[редагувати] %також перевантажено плаваючою точкою, що може стати несподіванкою для тих, хто має C або C ++.


21

Java не допускає перевантаження оператора. Кращим підходом є визначення методу для вашого класу для виконання дії: a.add(b)замість a + b. Тут ви можете ознайомитись з короткими мовами, викладеними з мови C, як тут: Особливості, вилучені з C та C ++


2
Важливим є завдання дизайну зробити незалежний контекст вихідних файлів Java. Намагаючись читати дуже великі (MLOC), макро важкі програми C мають дуже довгу криву навчання. Порівнювану (або більшу) програму Java важче зануритися, ніж невелику програму Java. Як сказав Гослінг: Мова для роботи програмістів із синіми комірами. [І кожен, хто вважає, що багатослів'я на коробці є згубними, повинні прочитати про хитання в експертному пізнанні.]
Тім Вілліскрофт,

2
Завдяки Oracle жодне з посилань на java.sun.com не працює. Чи можете ви, будь-ласка, надати оновлене посилання?
Syed Aqeel Ashiq

17

Ви не можете зробити це самостійно, оскільки Java не дозволяє перевантажувати оператора.

Однак за одним винятком. + і + = перевантажуються для об'єктів String.


8
Є багато інших прикладів перевантаження оператора на Java. Наприклад &, |і ^є перевантаженням для booleanцілісних типів. І справді, арифметичні та реляційні оператори перевантажені для різних числових типів. (Звичайно, семантика перевантажень набагато ближче ...)
Стівен 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 плутається рівність та ідентичність. Символ == (рівність) означає:
a. Рівність для примітивних типів.
б. Перевірка ідентичності для визначених користувачем типів, тому ми змушені використовувати функцію equals () для рівності.
Але ... Що це стосується перевантаження оператора?
Якщо мова дозволяє оператору перевантажувати користувача, він може надати належного значення оператору рівності.


Символ ==використовується для рівності в Java, як і в C і C ++. Це не має нічого спільного з перевантаженням оператора.
Гарячі лизання

2
Оператор ==, в Java означає лише рівність для примітивних типів. Для визначених користувачем типів означає Ідентичність. У C ++ семантика визначається користувачем, але повинна зберігати вбудовану семантику, рівність. Рядок a = "привіт"; Рядок b = "привіт"; булева c = (a == b);
Фернандо Пелліціоні

3
Тож те, що ви сказали у своєму першому коментарі, є неправильним. Правильно? Скажіть, будь ласка, як перевірити рівність та ідентичність на визначених користувачем типів у C. Ви маєте рацію, мій коментар щодо рівності є ОТ, але я уточнив це (див. "Додаткові"). Те, що я не створив мову програмування, не означає, що я не можу критикувати існуючу. Мені шкода, якщо ви бачили критику як релігійну війну.
Фернандо Пелліціоні

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

Хто не хоче бути / використовувати groovy? : 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.