Подтвердить что ты не робот

Почему Java не требует перегрузки оператора?

Почему Java не требует перегрузки оператора? Можно ли его поддерживать на Java?

4b9b3361

Ответ 1

Java разрешает только арифметические операции над элементарными числовыми типами. Это смешанное благословение, потому что, хотя удобно определять операторы на других типах (например, комплексные числа, векторы и т.д.), Всегда существуют зависящие от реализации идиосинкразии. Поэтому операторы не всегда делают то, что вы ожидаете от них. Избегая перегрузки оператора, он более прозрачен, какая функция вызывается когда. Мудрый дизайн движется в глазах некоторых людей.

Ответ 2

Java не нуждается в перегрузке оператора, потому что язык не нужен.

a + b - это просто "синтаксический сахар" для a.Add(b) (на самом деле, некоторые утверждают, что a.Add(b) является просто синтаксическим сахаром для Add(a,b))

Ответ 3

Этот связанный вопрос может помочь. Короче говоря, перегрузка оператора была умышленно устранена, когда Java была разработана из-за проблем с перегрузкой на С++.

Scala, новый язык JVM, имеет синтаксис, который позволяет перегрузку метода, которая очень похожа на перегрузку оператора, без ограничений перегрузки оператора С++. Например, в Scala можно определить метод с именем +. Также можно опустить оператор . и круглые скобки в вызове метода:

case class A(value: Int) {
   def +(other: A) = new A(value + other.value)
}

scala> new A(1) + new A(3)                                                           
res0: A = A(4)

Ответ 5

Не то, чтобы java не "нуждался" в перегрузке оператора, это просто выбор, сделанный его создателями, которые хотели сохранить язык более простым.

Ответ 6

Язык не требует перегрузки оператора. Некоторые считают, что Java выиграет от его добавления, но его упущение было опубликовано как преимущество настолько долго, что добавление его почти наверняка политически неприемлемо (и только после выкупа Oracle, что я даже включил бы "почти" ).

Контрапункт обычно состоит из постулирования некоторой бессмысленной (или даже противоречивой) перегрузки, такой как объединение двух сотрудников или перегрузка "+" для разделения. В то время как перегрузка операторов на таких языках, как С++, допускает это, отсутствие перегрузки оператора в Java мало что может предотвратить или даже смягчить проблему. someEmployee.Add(anotherEmployee) не улучшается по сравнению с someEmployee + anotherEmployee. Аналогично, если myLargeInteger.Add(anotherLargeInteger) фактически делит вместо добавления. По крайней мере, для меня эта аргументация в лучшем случае представляется неубедительной.

Однако существует и другое уважение, при котором опускание перегрузки оператора (почти наверняка) имеет реальную выгоду. Его упущение позволяет легче обрабатывать язык, что значительно упрощает (и ускоряет) разработку инструментов, которые обрабатывают язык. Для очевидного примера инструменты рефакторинга для Java гораздо более многочисленны и полны, чем для С++. Я сомневаюсь, что это может или должно быть зачислено конкретно и исключительно для поддержки перегрузки оператора на С++ и его упущения на Java. Тем не менее, общий подход к сохранению простой Java (включая упущение перегрузки оператора), несомненно, является важным фактором.

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

Требуя, чтобы пробелы могли упростить lexer крошечный бит, но в той степени, в какой это было сделано, он был бы полностью независим от перегрузки оператора, по крайней мере предполагая, что перегрузка оператора была выполнена, как и на С++, где только существующие токены используется 1.

Итак, если это не проблема, что это такое? Проблема с перегрузкой оператора заключается в том, что вы не можете жестко закодировать парсер, чтобы знать смысл оператора. С Java для некоторого заданного a = b + c существует ровно две возможности: a, b и c каждый выбирается из небольшого ограниченного набора типов, а смысл этого + иссякает на язык, иначе у вас есть ошибка. Таким образом, инструмент, который должен смотреть на b + c и имеет смысл, может сделать очень минимальный синтаксический анализ, чтобы гарантировать, что b и c относятся к типам, которые могут быть добавлены. Если они есть, он знает, что означает добавление, какой результат он производит и т.д. Если они не являются, это может подчеркнуть это в красных squiggles (или что-то еще), чтобы указать на ошибку.

Для С++ все совсем по-другому. Для выражения типа a = b + c;, b и c могут иметь почти полностью произвольные типы. + может быть реализована как функция-член типа b или может быть свободной функцией. В некоторых случаях у нас может быть несколько перегрузок операторов (некоторые из которых могут быть шаблонами), которые могли бы выполнять эту операцию, поэтому нам нужно сделать разрешение перегрузки, чтобы определить, какой именно компилятор будет фактически выбирать на основе типов параметров (и если некоторые из них являются шаблонами, правила разрешения перегрузки становятся еще более сложными).

Это позволяет нам определить тип результата из b + c. Оттуда мы в основном повторяем весь процесс снова, чтобы выяснить, какая (если таковая имеется) перегрузка используется для присвоения этого результата a. Он может быть встроен или может быть другой перегрузкой оператора, и может быть несколько возможных перегрузок, которые могли бы выполнять эту работу, поэтому нам нужно снова выполнить перегрузку, чтобы выяснить, как использовать правильный оператор.

Короче говоря, просто выяснить, что означает a = b + c; в С++, требуется почти весь интерфейс компилятора. Мы можем сделать то же самое в Java с гораздо меньшим подмножеством компилятора 2


  • Я полагаю, что все может быть несколько иначе, если вы допустили перегрузку оператора, например, ML, где более или менее произвольный токен можно обозначить как оператор, и этому оператору может быть предоставлена ​​более или менее произвольная ассоциативность и/или приоритет. Я считаю, что ML обрабатывает это полностью в разборе, а не в lexing, но если вы примете эту базовую концепцию достаточно дальше, я могу поверить, что она может повлиять на лексинг, а не просто на синтаксический анализ.
  • Не говоря уже о том, что большинство инструментов Java будут использовать JDK, который имеет полный компилятор Java, встроенный в JVM, поэтому инструменты обычно могут выполнять большинство таких анализов, не обращаясь непосредственно к разбору и тому подобное вообще.

Ответ 7

ОК Ну... у нас очень обсуждаемая и распространенная проблема. Сегодня в индустрии программного обеспечения существуют, в основном, два разных типа языков:

  • Языки низкого уровня
  • Языки высокого уровня

Это различие было полезно примерно за 10 лет до этого, ситуация в настоящее время немного отличается. Сегодня мы говорим о бизнес-готовых приложениях. Бизнес-модели - это некоторые конкретные модели, где программы должны соответствовать многим требованиям. Они настолько сложны и настолько строги, что кодирование приложения с использованием языка c или С++ было бы очень затратным временем. По этой причине гибридные языки придуманы.

Мы обычно знаем два типа языков:

  • Составитель
  • Интерпретированный

Хорошо, сегодня есть еще один:

  • Скомпилированный/Интерпретированный: одним словом: MANAGED.

Управляемые языки - это языки, которые скомпилированы для создания другого кода, отличного от исходного, но более сложного для обработки. Этот ПРОМЕЖУТОЧНЫЙ ЯЗЫК затем ПОТЕРЯЕТСЯ программой, которая запускает окончательную программу.

Это общая динамика, с которой мы познакомились на Java... Это выигрышный подход для бизнес-приложений. Ну, теперь идем на ваш вопрос...

Перегрузка операторов - это вопрос, который касается также множественного наследования и других передовых характеристик языков низкого уровня. Java, а также С#, Python и т.д. - это управляемый язык, который упрощается для написания и полезен для создания сложных приложений за очень короткое время. Если бы мы включили перегрузку оператора в Java, язык стал бы более сложным и трудным в обращении.

Если вы программируете на С++, вы наверняка понимаете, что перегрузка оператора очень очень деликатная, потому что это может привести к очень сложным ситуациям, и иногда компилятор может отказаться от компиляции из-за конфликтов и т.д. Введение в перегрузку оператора будьте осторожны. ЯВЛЯЕТСЯ МОЩНЫМ, но мы платим эту мощность с невероятно большой нагрузкой на проблемы.

OKOK ЭТО ИСТИННО, вы можете сказать мне: "ЭЙ, но С# использует перегрузку оператора... Что, черт возьми, вы мне говорите, почему С# поддерживает их, а Java нет?". Ну, это ответ. С#, да, реализует перегрузку оператора, но это не похоже на С++. Существует много операторов, которые не могут быть перегружены в С#, например, "новые" или многие другие, которые вы можете перегрузить в С++... Таким образом, С# поддерживает перегрузку оператора, но на гораздо более низком уровне, чем на С++ или на других языках, полностью поддерживающих его. Но это не лучший ответ на предыдущий вопрос... Реальный ответ: С# сложнее Java. Это про, но и con. Решать вопрос о том, где разместить язык: высокий уровень, высокий уровень, очень высокий уровень? Ну, Java не поддерживает перегрузку, потому что хочет быть быстрым и простым в управлении и использовании. При внедрении перегрузки op язык также должен нести большое количество проблем, вызванных этой новой функциональностью.

Это точно так же, как вопрос: "Почему Java не поддерживает множественное наследование?" Потому что это чрезвычайно сложно управлять. Подумайте об этом... ЭТО БЫЛО НЕВОЗМОЖНО, если управляемый язык поддерживает множественное наследование... Нет общего дерева классов, нет класса объекта как общего базового класса для всех классов, нет возможности повышения (а) и многих проблем для обработки, управлять, предвидеть, держать в счете...

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

Многие другие, здесь, также сказали вам, что перегрузка бесполезна. Ну, я принадлежу тем, кто думает, что это неправда. Ну, если вы так думаете (перегрузка op бесполезна), то и многие другие функции управляемых языков тоже бесполезны. Подумайте о интерфейсах, классах и т.д., Вам они действительно не нужны. Вы можете использовать абстрактные классы для реализации интерфейса... Давайте посмотрим на С#... так много синтаксиса сахара, LINQ и т.д., Они действительно не нужны, НО ОНИ ОТКЛЮЧАЮТ ВАШУ РАБОТУ... Ну, на управляемых языках все, что закрепляет процесс разработки, приветствуется и не подразумевает бесполезности. Если вы считаете, что такие функции не полезны, как весь язык сам по себе будет бесполезен, и все мы вернем программирование сложных приложений в С++, ada и т.д. Добавленная ценность управляемых языков должна быть измерена прямо на этих элементах.

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

Я знаю, может быть, я немного долго, но надеюсь, что это поможет. Bye

Ответ 8

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

Ответ 9

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

Перегрузка оператора - это синтаксический сахар, чтобы выразить операцию с использованием (арифметических) символов. По понятным причинам разработчики языка программирования Java решили отказаться от поддержки перегрузки оператора на языке. Это объявление можно найти в документе Java Language Environment:

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

По моему личному мнению, это мудрое решение. Рассмотрим следующий фрагмент кода:

String b = "b";
String c = "c";
String a = b + c;

Теперь довольно очевидно, что b и c объединяются, чтобы получить a. Но если учесть следующий фрагмент, написанный с использованием гипотетического языка, который поддерживает перегрузку оператора, довольно очевидно, что использование перегрузки оператора не делает для считываемого кода.

Person b = new Person("B");
Person c = new Person("C");
Person a = b + c;

Чтобы понять результат вышеуказанной операции, нужно просмотреть реализацию перегруженного оператора сложения для класса Person. Разумеется, это делает утомительную сессию отладки, и код лучше реализован как:

Person b = new Person("B");
Person c = new Person("C");
Person a = b.copyAttributesFrom(c);

Ответ 10

Отметьте Особенности Java Удалены из C и С++ p 2.2.7 Больше перегрузки оператора.

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