Критика Java

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

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

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

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

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

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

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

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

Поскольку обобщения были реализованы с помощью стирания типов (англ.), действительный тип параметра шаблона недоступен во время выполнения программы. Поэтому следующие операции невозможны в 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 (англ.), такие как Флаги исключений и выпрямленные округления - возможности предусмотренные в качестве обязательных по стандарту 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, 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.
  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 (2003-1-1). Проверено 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
  13. FreeTTS - A Performance Case Study, 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.

Ссылки[править | править вики-текст]