Критика Java

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

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

Общая характеристика[править | править код]

Критика Java, как и других распространённых и популярных ЯВУ, достаточно обширна и разнородна. Можно выделить следующие основные аспекты этой критики.

Базовая идеология Java.
Критикуется сама идея создания системы, базирующейся на языке высокого уровня, компилируемого в байт-код виртуальной машины, и создания для каждой вычислительной платформы интерпретатора байт-кода. Также мишенью для критики может быть встроенная в Java-систему подсистема сборки мусора.
Язык и базовая платформа Java.
Критикуются почти все технологические решения разработчиков Java, в том числе заимствование синтаксиса C/C++, идеология иерархии пакетов и её связь с иерархией файлового дерева исходных текстов проекта, наличие, набор и особенности функционирования базовых скалярных типов данных, арифметика.
Реализация.
Критикуется реализация вычислений с плавающей запятой, обращается внимание на уязвимости во встроенной системе безопасности. Критикуется реализация механизмов обобщённого программирования в Java. Лозунг компании Sun Microsystems «Напиши один раз, запускай везде[en]» (англ. write once, run everywhere) критики переделали в «напиши один раз, отлаживай везде» («англ. write once, debug everywhere»), ссылаясь на многочисленные различия в базовой платформе, которые обязательно нужно учитывать при написании любых программ на Java, отличных от тривиальных.[прояснить]
Эффективность.
Критические замечания о недостаточной эффективности Java в основном относятся к первым версиям реализации языка и платформы, выпущенным в середине 1990-х годов. Впоследствии лавинообразный рост производительности процессоров и объёмов оперативной памяти сделал критику производительности Java гораздо менее актуальной. Тем не менее, до сих пор можно встретить утверждения, что «генетические особенности» Java-систем приводят к избыточным затратам памяти и процессорного времени, не предоставляя при этом равноценных преимуществ перед более экономичными средствами разработки.
Развитие.
Часть критиков считает, что созданные владельцами авторских прав на язык механизмы развития языка тормозят включение в него различных новшеств. Можно встретить и прямо противоположные мнения, согласно которым изменение Java от версии к версии идёт слишком активно, и разработчики внедряют в язык новые элементы, руководствуясь не столько техническими соображениями, сколько модой, что приводит к неоправданному усложнению языка.

Синтаксис и семантика языка[править | править код]

Обобщения в Java[править | править код]

К моменту добавления средств обобщённого программирования в Java 5.0 платформа Java имела большую, активно используемую иерархию классов, многие из которых были устаревшими. Чтобы обеспечить обратную совместимость и возможность повторного использования существующих классов, обобщения были реализованы с помощью механизма стирания типов (в байт-коде обобщённые типы заменяются на нетипизированные ссылки, что позволяет виртуальной машине исполнять код с обобщениями точно так же, как и обычный), что наложило серьёзные ограничения на их использование. В других языках обобщения дают больше возможностей, поскольку реализованы с помощью других механизмов.[1][2] Так, например, на платформе .NET реализация обобщений была внедрена непосредственно в ядро виртуальной машины, исполняющей байт-код, что позволило ценой некоторого усложнения избежать характерных для Java ограничений и, одновременно, существенно облегчило включение обобщений в любые реализуемые на данной платформе языки.

Поскольку обобщения были реализованы с помощью стирания типов[en], действительный тип параметра шаблона недоступен во время выполнения программы. Поэтому следующие операции невозможны в Java: [3]

public class MyClass<E> {
    public static void myMethod(Object item) {
        if (item instanceof E) { // Compiler error
            ...
        }
        E item2 = new E(); // Compiler error
        E[] iArray = new E[10]; // Compiler error
    }
}

Беззнаковые целочисленные типы данных[править | править код]

В Java не реализованы встроенные беззнаковые целочисленные типы данных.[4] Беззнаковые данные часто генерируются в программах, написанных на Си, и отсутствие этих типов данных в Java препятствует прямому обмену данными между программами, написанными на Си, и программами, написанными на Java. Большие числа без знака также используются во многих задачах числовой обработки, в том числе в криптографии, что может сделать Java менее подходящей для автоматизации этих задач, чем другие языки программирования.[5] Хотя возможно частично обойти эту проблему с помощью преобразования кода и использования других типов данных, это делает работу с Java обременительной при обработке беззнаковых данных. Хотя тип данных для 32-разрядных целых чисел со знаком может быть использован для хранения значения 16-разрядного беззнакового числа без потерь, 32-разрядное беззнаковое число потребует 64-разрядного целого типа со знаком, и, соответственно, 64-разрядное беззнаковое значение не может быть корректно преобразовано ни в один целочисленный тип данных в Java, поскольку в Java не существует типов данных для обработки чисел с разрядностью, большей, чем 64. В любом случае, увеличивается в два раза потребление памяти, и любая логика, которая зависит от правил переполнения дополнительного кода, как правило, должна быть переписана. В качестве альтернативы можно использовать знаковые целочисленные типы данных Java для эмуляции беззнаковых целочисленных типов данных того же размера, однако это требует детального знания работы со сложными битовыми операциями.[6] и снижает читаемость кода.

Операции над числами с плавающей точкой[править | править код]

Хотя операции над числами с плавающей точкой в Java в основном базируются на стандарте двоичной арифметики с плавающей точкой IEEE 754, некоторые функции не поддерживаются даже при использовании модификатора strictfp[en], такие, как Флаги исключений и выпрямленные округления — возможности, предусмотренные в качестве обязательных по стандарту IEEE 754. Кроме того, типы данных повышенной точности с плавающей точкой допускаются стандартом IEEE 754, реализованы во многих процессорах, не реализованы в Java.[7][8][9]

Производительность[править | править код]

В первых версиях Java (до того, как HotSpot был реализован в Java 1.3 в 2000 году) было много критики по поводу низкой производительности. Java продемонстрировала работу на скорости, сравнимой с оптимизированным машинным кодом, а современные реализации виртуальной машины Java в тестах на производительность регулярно показывают одни из лучших результатов среди доступных языковых платформ — обычно в пределах 3 позиций по отношению к Си/C++.[10]

Производительность Java существенно улучшилась в новых версиях по сравнению с ранними.[11] Производительность JIT-компиляторов по сравнению с универсальными компиляторами в некоторых искусственных специально подобранных тестах оказалась сравнимой.[11][12][13]

Байт-код Java может быть либо интерпретирован во время выполнения виртуальной машиной, либо он может быть скомпилирован во время загрузки программы или во время её выполнения в машинный код, который работает непосредственно на компьютере. Интерпретация происходит медленнее, чем выполнение машинного кода, а компиляция во время загрузки программы или во время её выполнения снижает производительность за счёт затрат времени на компиляцию. Современные производительные реализации виртуальной Java-машины используют компиляцию, поэтому (после срабатывания JIT-компиляции) приложение показывает производительность, близкую к платформенно-ориентированному коду.

Безопасность[править | править код]

В 2010 году значительно увеличилось количество эксплойтов для обхода ограничений песочницы JVM в браузерах, в результате чего Java стала более атакуемой, чем Acrobat и Flash.[14]

Критики полагают, что обновлённые версии JVM не используются, поскольку многие пользователи просто не знают о том, что у них на компьютере установлена JVM, и поскольку многие пользователи не знают, как обновить JVM. Что же касается корпоративных компьютеров, то многие компании ограничивают права пользователей на установку программного обеспечения и слишком медленно устанавливают обновления.[14][15]

В последних версиях JVM есть опции доступности Java в браузерах.

См. также[править | править код]

Примечания[править | править код]

  1. Generics in Java. Object Computing, Inc.. Дата обращения: 9 декабря 2006. Архивировано 3 сентября 2012 года.
  2. What's Wrong With Java: Type Erasure (6 декабря 2006). Дата обращения: 9 декабря 2006. Архивировано 3 сентября 2012 года.
  3. Type Erasure. Архивировано 3 сентября 2012 года.
  4. Types, Values and Variables Архивная копия от 28 февраля 2012 на Wayback Machine, Java Languaege Specification, 2-nd ed.
  5. Java libraries should provide support for unsigned integer arithmetic. Bug Database, Sun Developer Network. Oracle. Дата обращения: 18 января 2011. Архивировано 3 сентября 2012 года.
  6. Owen, Sean R. Java and unsigned integers Java and unsigned int, unsigned short, unsigned byte, unsigned long, etc. (Or rather, the lack thereof) (5 ноября 2009). Дата обращения: 9 октября 2010. Архивировано 20 февраля 2009 года.
  7. Kahan, W.; Joseph D. Darcy.: How Java's Floating-Point Hurts Everyone Everywhere (PDF) (1 марта 1998). Дата обращения: 9 декабря 2006. Архивировано 3 сентября 2012 года.
  8. Types, Values, and Variables. Sun Microsystems. Дата обращения: 9 декабря 2006. Архивировано 3 сентября 2012 года.
  9. Java theory and practice: Where's your point? Tricks and traps with floating point and decimal numbers. IBM (1 января 2003). Дата обращения: 19 ноября 2011. Архивировано 3 сентября 2012 года.
  10. Computer Language Benchmarks Game: Java vs Gnu C++. Debian.org. Дата обращения: 19 ноября 2011. Архивировано 3 сентября 2012 года.
  11. 1 2 J.P.Lewis and Ulrich Neumann. Performance of Java versus C++. Graphics and Immersive Technology Lab, Университет Южной Калифорнии. Архивировано 3 мая 2012 года.
  12. The Java is Faster than C++ and C++ Sucks Unbiased Benchmark. Дата обращения: 15 ноября 2011. Архивировано 12 июня 2010 года.
  13. FreeTTS — A Performance Case Study Архивировано 25 марта 2009 года., Willie Walker, Paul Lamere, Philip Kwok
  14. 1 2 Researchers Highlight Recent Uptick in Java Security Exploits. Архивировано 3 сентября 2012 года.
  15. Have you checked the Java? Архивировано 3 сентября 2012 года.

Ссылки[править | править код]