Как оператор + ведет себя по-разному с числами и строками в Java? - PullRequest
13 голосов
/ 02 июня 2010

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

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

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

Ответы [ 9 ]

16 голосов
/ 02 июня 2010

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

«В Java нет концепции перегрузки операторов» верно только в том случае, если разработчики не могут перегружать операторы.

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

13 голосов
/ 02 июня 2010

Не перегружает ли язык 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: Сын Лупера :

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


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

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


Приложение

Ссылки JLS

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

10 голосов
/ 02 июня 2010

Оператор + перегружен. Java просто не позволяет вам перегрузить его самостоятельно.

5 голосов
/ 02 июня 2010

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

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

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

4 голосов
/ 02 июня 2010

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

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

0 голосов
/ 02 июня 2010

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

0 голосов
/ 02 июня 2010

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

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

Для String «сложение» создается StringBuilder и используется за кулисами

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

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

и т.д ...

0 голосов
/ 02 июня 2010

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

0 голосов
/ 02 июня 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...