Как оператор + ведет себя по-разному с числами и строками в Java?

В Java нет понятия перегрузки оператора.

Оператор Still + ведет себя как оператор сложения с числами и конкатенатным оператором со строками. Это похоже на поведение перегрузки оператора.

Итак, есть ли у Java перегрузка оператора?

Ответ 1

Перегружает ли язык Java некоторые операторы?

ДА! Как вы узнали, оператор + может означать две разные вещи: конкатенацию строк или числовое дополнение. Это, по определению, перегрузка оператора.

Здесь список всех операторов Java:

JLS 3.12 Операторы

Следующие 37 токенов - это операторы, образованные из символов ASCII:

  =     >     <     !     ~     ?      :
  ==    <=    >=    !=    &&    ||     ++     --
  +     -     *     /     &     |      ^      %     <<     >>    >>>
  +=    -=    *=    /=    &=    |=     ^=     %=    <<=    >>=   >>>=

Некоторые из этих операторов перегружены. Вот несколько примеров:

System.out.println(   3 + 4 + "X"     ); // prints "7X"
System.out.println(   3 + (4 + "X")   ); // prints "34X"
System.out.println(   "X" + 3 + 4     ); // prints "X34"
System.out.println(   "X" + (3 + 4)   ); // prints "X7"

System.out.println(0 == 0);                           // prints "true"
System.out.println(new Integer(0) == new Integer(0)); // prints "false"

System.out.println(true & (1 & 2) == 12); // prints "false"

Можем ли мы перегрузить операторы, определенные на языке Java?

АБСОЛЮТНО НЕ! Все Java-операторы имеют значение, точно указанное в спецификации языка. Не существует "экстралингвистической" семантики: оператор Java может НИКОГДА делать то, что не указано языком.

То есть, если язык не меняется, гарантируются следующие истины:

  • someString + whatever ВСЕГДА конкатенация строк
  • referenceType == anotherReferenceType ВСЕГДА ссылочное равенство
  • Нет фанковых вещей вроде 3 * "a lady" или "my heart" / 2 или даже 10**3 ~= 999

Как видно из приведенного выше фрагмента, даже текущее состояние перегрузки оператора все еще может быть довольно запутанным, особенно для новичков. Не допуская чрезмерно лингвистических перегрузок, по крайней мере эта путаница ограничена: как только программист узнает о том, что делают все операторы на языке Java в разных перегруженных сценариях, их точная семантика во всем коде Java становится ясной и точной.

Перегрузка оператора может быть довольно запутанной. Некоторые считают, что это "плохо", как есть. Чтобы позволить пользователям перегружать Java-операторы, чтобы что-то делать вне спецификации языка, может привести к еще большему путанице.

Здесь выдержка из Java Puzzlers, Головоломка 30: Сын лупера:

Урок для разработчиков языков - это то же самое, что и [две другие головоломки]. Перегрузка оператора может сбить с толку. Возможно, оператор + не должен был перегружаться для конкатенации строк. Возможно, стоит предоставить оператор конкатенации строк, но он не должен быть +.


Вам нужен С++ для поддержки перегрузки операторов в Java?

NOPE! Это не имеет никакого отношения к этому. Все, что нужно сделать компилятору Java, - это проанализировать исходный код программы в соответствии с грамматическими правилами языка и определить для каждого оператора типы типов операндов. Эту информацию достаточно, чтобы определить, что означает смысл оператора, и затем действовать соответственно, как указано языком.


Приложение

Ссылки JLS

Выявление вопросов

Ответ 2

В основном это перегрузка оператора - просто встроенная в язык.

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

Спецификация языка, и, строго говоря, все арифметические операторы перегружены для обработки вычислений, которые включают более одного численного типа. И даже там, это иногда создает путаницу (например, нужно сделать один операнд до double, если вы хотите, чтобы divsion из значений int дал дробные результаты).

Ответ 3

Оператор + перегружен. Java просто запрещает ВАМ перегружать его самостоятельно.

Ответ 4

Оператор Concat - это специальная поддержка, предоставляемая на Java. Цитата из Javadoc ниже.

Язык Java предоставляет специальные поддержка конкатенации строк оператора (+), а для преобразования другие объекты для строк. строка конкатенация осуществляется через класс StringBuffer и его добавление метод. Преобразования строк реализуется методом toString, определяемый Object и унаследованный всеми классами Java. Для дополнительная информация о строке конкатенации и преобразования, см. Гослинг, Радость и Стил, Ява Спецификация языка.

Для получения информации см. this

Ответ 5

Полиморфная обработка операторов в Java является формой перегрузки оператора, поскольку этот термин традиционно используется. Например, прочитайте страницу wikipedia в перегрузке оператора, и вы увидите стиль перегрузки Java, упомянутый в первом абзаце.

"В компьютерном программировании перегрузка оператора (менее известный как операторный полиморфизм ad-hoc) является специфическим случаем полиморфизма, в котором некоторые или все операторы, такие как +, = или ==, имеют разные реализации в зависимости от типов их аргументы. Иногда перегрузки определяются языком, иногда программист может реализовать поддержку для новых типов.

Ответ 6

Функциональность, о которой вы говорите, просто встроена в Java. У вас все еще нет контроля над перегрузкой оператора.

Ответ 7

Java не позволяет программистам перегружать операторы, но имеет встроенную поддержку для операторов по некоторым своим встроенным типам (я думаю, что String - единственный объект с поддержкой любого оператора, кроме авто-бокса).

Ответ 8

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

Оператор скомпилируется в разные инструкции байткода, в зависимости от операндов:

Для String "добавление" создается и используется сценарий StringBuilder за кулисами

Для добавления int используется команда iadd JVM.

Для двойного добавления используется команда dadd JVM.

и т.д...

Ответ 9

Я чувствую, что это ведет себя скорее как неявное преобразование одного типа в другое, чем как перегрузка оператора.