Примечание редактора . Находясь на канале Java, большинство из нас очень хорошо знают язык и находятся в его экосистеме по крайней мере пару лет. Это дает нам рутину и опыт, но также вызывает определенное видение туннеля. В новой серии Outside-In Java не-Javaists расскажут нам о нашей экосистеме.
Я не самый большой поклонник Java. Я могу читать Java, если это необходимо, и я написал некоторые в чрезвычайных ситуациях, но я не привыкаю к этому. У меня такие же стереотипные впечатления, как и у других людей, не относящихся к Java: он большой и медленный и написан исключительно людьми, которые носят галстуки во время программирования.
Возможно, я больше всего известен благодаря сложной деконструкции PHP , но это произошло из-за того, что PHP вызвал во мне уникальное разочарование. Ява в основном вдохновляет, ах, скука.
Но ждать. PHP популярен, потому что он имеет особое преимущество: он удаляет несколько шагов из кошмарного ритуала, который является веб-разработкой. У Java нет сравнимого огромного преимущества, поэтому она должна что- то делать правильно. В противном случае Oracle не стала бы хвастаться девятью триллионами устройств, работающих на Java. Это не обеспечило бы силы значительного числа крупных веб-сайтов. Доминирующая ОС для смартфонов не будет полностью построена на ней. У меня не было бы тостера, который управляет JVM. (Это работает лучше, чем вы думаете! Вам просто нужно немного подождать, пока он прогреется.)
Так что, может быть, может быть, у меня все в Java неправильно Может быть, я был несправедлив к этому. Может быть.
Возможно, пришло время пересмотреть мои предвзятые представления о Java. Разрушить некоторые мифы, если хотите.
Для справки, я баловался несколькими языками, но в основном я делаю Python и мне нравятся многие его дизайнерские решения. Python имеет небольшое философское совпадение с Java, так что это интересная точка сравнения.
Ява медленная
Ява определенно чувствует себя большой и медленной для меня. Слово похоже на патоку в моем мозгу. Когда я думаю о Java, мне вспоминаются очень немногие встречи с ним на рабочем столе. Возможно, самым печально известным был Azureus, Java-клиент BitTorrent, который все использовали для загрузки выпусков Ubuntu более десяти лет назад. Это было на удивление вяло, учитывая, что все, что он делал, это скачивал файлы, и все соскочили с µTorrent. µTorrent, конечно, написан на C ++, что делает его более быстрым и производительным.
Дело в том, что это не имеет никакого смысла. Единственный клиент BitTorrent, который я использовал годами, — это Deluge, написанный на Python . (C) Python определенно не так быстр, как Java, но Deluge всегда был для меня быстрым. JVM используется отчасти потому, что он довольно быстрый, так откуда возникла эта связь с медлительностью?
Как бы нам ни хотелось думать иначе, здесь сложно сделать какие-либо реальные измерения; на скорость влияет так много факторов, что даже сравнение одной программы с самой собой ненадежно, не говоря уже о сравнении двух совершенно разных частей программного обеспечения. Машина увязла, делая что-то еще? GC начал в неподходящее время? Один язык лучше в конкретной задаче? Я использую плохую JVM? Одно приложение написано лучше, чем другое? Даже если бы я мог контролировать все эти факторы, все равно сложно измерить восприятие скорости, о чем это на самом деле. Лучшее, что я могу сделать — это обдумать это.
Медленные программы, медленный язык
И я подозреваю, что здесь немного смещения подтверждения. Если программа медленная, мы обвиняем ее, но если программа на Java медленная, мы обвиняем Java . Ява даже в конкретном недостатке здесь; Легко заметить, что программа с графическим интерфейсом написана на Java, так как Swing торчит как больной большой палец, но сложнее быть уверенным, что она написана на C ++ или подобном.
По моему опыту, это особенно заметно в игровых кругах, где вы можете найти глубокое понимание производительности игры от людей, которые никогда не писали ни строчки кода. Видите ли, Minecraft работает медленно, потому что он написан на Java, а Starbound работает медленно, потому что разработчики не «оптимизировали» его. Что бы это ни значило.
Другой возможный фактор, хотя я не знаю, насколько это верно: у меня сложилось впечатление, что многие разработчики пишут на C ++, потому что хотят, но пишут на Java, когда это необходимо? Я сталкивался с большим количеством кода на C ++, который не имеет веских причин для написания на C ++, но с большим количеством кода Java с историей, которая начинается «мы написали это с Rails и портировали его, когда он стал слишком медленным». (Или «это для Android, так что мы должны были».) Другими словами, Java, кажется, является обычным средством ускорения уже слишком медленного кода, поэтому любая данная Java-программа вполне может выполнить очень тяжелую работу. , Дело не в том, что Java медленная; дело в том, что медленные программы, как правило, пишутся на Java. Проблема самоотбора.
Между тем, большая часть C ++ написана просто вопреки. Или, скорее, есть подмножество программистов, которые одержимы максимальной производительностью и будут стремиться к C ++ независимо от того, нуждаются ли они в этом или нет , потому что противодействие «голому металлу» дает им теплые размышления и полностью оправдывает риск ложных ошибок и памяти. ошибки. Таким образом, данная программа на C ++ не обязательно выполняет интенсивную работу, которая оправдывает использование C ++.
JIT в ошибке?
Первоначально я испытывал искушение обвинить некоторую медлительность в разогреве JIT, но я не уверен, что это вероятно. Я стал чаще испытывать разогрев JIT, так как я больше использую PyPy. PyPy — это реализация JITted Python (написанная сама по себе, отсюда и название), и один из больших барьеров на пути более широкого внедрения заключается в том, что для прогрева требуется несколько секунд. Программы Python, которые запускаются более или менее мгновенно со стандартным Python, вызывают заметную задержку при запуске с PyPy — и поскольку Python обычно используется для инструментов командной строки, эта задержка затрагивает довольно много программ.
Но для всего, что требует более полминуты, PyPy работает значительно быстрее. Я ожидаю, что у JVM будет гораздо более продвинутый JIT, чем у относительно молодого PyPy, поэтому время разогрева будет еще короче. Я сомневаюсь, что Java получит репутацию медленной только потому, что она немного затухает в первые двадцать или тридцать секунд.
Я также наблюдал, как разогрев JIT происходил в реальном времени с LÖVE, игровым движком, который использует LuaJIT. Если вы рисуете частоту кадров на экране, вы можете наблюдать, как она начинается около 10, а в течение нескольких секунд увеличивается до 60. После этого все работает нормально. Опять же, замедление довольно короткое, и у меня никогда не создается впечатление, что двигатель или JIT в целом работают медленно.
Ява как игрушка
Я готов поспорить, что это в основном сплетни, появившиеся еще тогда, когда появилась Java. Конечно, некоторые разработчики C ++ восприняли бы Java как переизобретение C ++, которое было комично медленным … по сравнению с C ++ . У оригинальной Sun JVM не было JIT в течение нескольких лет, поэтому очень ранняя Java интерпретировалась как байт-код, как это делает большинство Python, — но на гораздо более медленном оборудовании.
Это имеет некоторый смысл и с культурной точки зрения. Java была представлена как «серьезный» язык — то есть конкурент C ++ — в то время, когда единственным «серьезным» языком был, например, C ++. Все, что пахло интерпретируемым языком, в значительной степени считалось игрушкой. Я имею в виду даже больше, чем сейчас. Если бы весь спектр «языков, которые любой использовал бы для серьезной разработки», варьировался от C ++ до Java, то, конечно, Java выглядела бы как неуклюжий зверь. Автоматическая сборка мусора? Что ты, какой-то младенец ? Бьюсь об заклад, ваш язык не может даже segfault.
Перенесемся на двадцать лет назад, и половина моей операционной системы написана на JavaScript. Я даже однажды написал настольное приложение на Perl (yolo). По крайней мере, Java выглядит лучше в сравнении?
Ява раздутая
Мне не нравится слово «раздувать». Это ничего не значит. Или, скорее, это означает «вещи, которые меня не волнуют», а это бесполезная критика.
Однажды мне кто-то сказал одновременно: «Они не использовали GIMP для художественных работ, потому что они раздутые, и» они были разочарованы гораздо более простым Paint.NET, потому что в нем отсутствовала неясная функция питания, в которой они нуждались… которую имеет GIMP.
В интересах точности, вот некоторые вещи, которые «блат» может означать.
Java-программы используют много памяти
Любое упоминание об использовании памяти Java напоминает мне историю, когда я работал в $ TECHCOMPANY. Я отвечал за заботу и поддержку нашей системы сборки, в которой использовался Closure Compiler, «компилятор JavaScript-JavaScript», написанный на Java.
Система сборки запустила Closure как java -Xmx1024M ...
При ручном вызове Closure я иногда забывал о загадочном -Xmx
Позже я обнаружил несколько непонятную переменную окружения _JAVA_OPTIONS
Когда я в конце концов заглянул в нее, я обнаружил захватывающее столкновение намерений.
Мы использовали разделяемые dev-машины, каждая по 64 ГБ. У нас был ulimit -v
По умолчанию наша JVM пыталась выделить четверть физического ОЗУ машины при запуске — 16 ГБ. Распределение не удалось, поэтому JVM немедленно закрылась. ( Документация действительно предполагает, что куча должна быть ограничена не более чем 1 ГБ по умолчанию, но выглядит неправильно ).
Это не совсем неразумно для JVM. Linux с радостью выделит большие ресурсы, которых на самом деле нет, и пока процессы не пытаются использовать всю эту память, все работает отлично. JVM воспользовалась этим, чтобы выделить огромный блок заранее, избегая необходимости большого (медленного) распределения позже. ulimit
(Увы, ulimit -m
В моей голове эта история «когда-то Java хотела 16 ГБ». Я знаю, что это нечестно, но резонанс с смутным ощущением говорит о том, что Java обычно называют боровом памяти. Кажется, даже сама Java думает, что ей может понадобиться столько памяти. Тем не менее, если я смотрю мимо стереотипа, я не могу придумать конкретную необоснованную причину, почему это было бы так.
Я могу себе представить, что большинство факторов скорости применимы и здесь: Java обвиняют, когда большая Java-программа, но C ++ не обвиняют, когда большая C ++; большие задачи обычно заканчиваются написанием на Java; Разработчики C ++, которые гипероптимизируют, могут смеяться над сборкой мусора и накладными расходами для каждого объекта.
Ах, но хотя скорость трудно определить количественно даже для одной программы, размер гораздо более детерминирован. Одно и то же значение одного и того же типа обычно занимает одинаковое количество места от запуска к запуску. Я знаю, что объект CPython имеет 16 байтов служебных данных, например — указатель типа и refcount. Я менее уверен в издержках объекта в Java — точное использование памяти рассматривается как деталь реализации виртуальной машины, а в Java есть несколько конкурирующих виртуальных машин общего пользования. (Я знаю о CPython только из чтения исходного кода, с которым я уже знаком.) Но я серьезно сомневаюсь, что для любой JVM потребуется больше служебных данных, чем для Python, а в некоторых случаях — гораздо меньше — в Python нет распакованных примитивов. , В конечном счете, Java не должна быть намного хуже, чем Python, и я не думаю о Python как о бреде памяти, поэтому, конечно, я не должен думать о Java как об одном.
Фальшивая наука
Достаточно спекуляций. Если размер более надежно измерим, давайте проведем некоторые измерения. Вот ужасное ненаучное сравнение начального использования памяти несколькими произвольно выбранными настольными программами.
- XMind (Java), картограф: 416 МБ
- yEd (Java), редактор графиков (как в блок- схемах , а не y = x² ): 372 МБ
- jDiskReport (Java), отчет о дисковом пространстве: 228 МБ
- muCommander (Java), файловый браузер в стиле MC: 183 МБ
- FreeMind (Java), еще один картограф: 181 МБ
- SLADE (C ++ / wxWidgets), редактор карт Doom: 93 МБ
- GIMP (C ++ / GTK), редактор изображений: 88 МБ
- LMMS (C ++ / Qt), цифровая звуковая рабочая станция: 75 МБ
- Deluge (Python / GTK), клиент BitTorrent: 85 МБ
(Между прочим, все Java-программы запускаются как минимум с 11 ГБ виртуальных — за исключением FreeMind, который поставляется со сценарием оболочки, который добавляет -Xmx
Вау. Я не ожидал такой большой разницы, даже зная, что здесь много факторов, влияющих на Java. GTK и Qt являются общими библиотеками, которые могут использоваться другими процессами, и даже пользовательский интерфейс Python оборачивает эти библиотеки и сохраняет большую часть своих данных на уровне C; Swing живет почти полностью на земле Java и использовался только той программой, которую я открыл. У Java, конечно, есть целое время выполнения (которое, кажется, занимает базовый уровень 26 МБ), тогда как «время выполнения» C ++ является микроскопическим. Python также имеет время выполнения, но Deluge — намного более простая программа, чем другие; это единственная другая не-C ++ вещь, которую я имею под рукой. Или XMind и yEd могут быть просто непредставительными по какой-то другой причине.
Java (как и Python) также должна помнить много отладочной информации, которая обычно не учитывается в выпущенных программах C ++, для размышлений и трассировки стека. Сборка мусора имеет тенденцию заменять запасную память на скорость; Я не знаю подробно, как работает GC моей JVM, но я видел GC со 100% или более накладными расходами, поэтому я не удивлюсь, если бы это было существенным фактором здесь. Я хочу сказать, что у GC также есть проблемы с фрагментацией, которые трудно решить.
Строки Java бесполезны
Я подозреваю, что другой огромный преступник — это String
Строки Java — это «Unicode», в том смысле, как «Unicode» был определен в 1990-х годах. Видите ли, Unicode изначально обещал, что в нем никогда не будет больше 65 536 символов, поэтому двух байтов будет достаточно для представления чего-либо. Windows API, по крайней мере один инструментарий GUI, Java, JavaScript (который, вероятно, скопировал его из Java), и другие бедняги приняли это близко к сердцу и объявили, что все строки будут использовать двухбайтовые символы. Кодировка символов была решена навсегда.
Пока Unicode не стал «упс» и пообещал, что в нем никогда не будет больше 1114111 символа, так что трех байт будет достаточно для представления чего-либо, но никто не имеет трехбайтовый целочисленный тип, поэтому давайте округлим его до четырех. Сейчас Java находится в очень неловком положении. Текст ASCII занимает вдвое больше места, чем нужно. Но Java String
Худшее из обоих миров.
Строки могут быть значительной частью использования памяти графическим интерфейсом, что связано с множеством меток и всплывающих подсказок, и в этом случае это будет иметь огромное значение. Я знаю, что XML и файлы конфигурации довольно популярны и в мире Java, и они, естественно, создают тонны строк. Я вижу, что Java 9 настроена на использование более компактной схемы , где строки ASCII будут прозрачно использовать только один байт на символ под капотом. Python переключился на аналогичную схему несколько выпусков назад, и использование памяти Django (веб-приложением) сократилось на целых 40% по сравнению с двухбайтовой сборкой. Java может увидеть сопоставимые улучшения в текстовых программах; отчет о влиянии на эталонный тест на сервере показал 21% улучшение использования кучи.
В заключение
Я вошел в это ожидание, чтобы обнаружить, что Java была намного более компактной, чем я думал, и … это не совсем произошло. Даже 228 МБ не так уж и плохо, но 416 МБ немного смешно. О, я случайно оставил тебя бегущим на ночь; он вырос до 854 МБ, несмотря на то, что ничего не делал, поставив его на третье место после художественной программы с несколькими большими открытыми полотнами и моим браузером с несколькими сотнями открытых вкладок. Я не знаю, что он делает или кого винить, но это выглядит не очень хорошо. Интересно, что FreeMind и XMind были лучшими и худшими соответственно, несмотря на то, что они были одного и того же жанра программного обеспечения и написаны на одном языке.
Теперь, чтобы быть немного честным по отношению к Java, я, честно говоря, не заметил бы использования памяти, если бы не искал ее. У меня есть 32 ГБ оперативной памяти по причине. И все же… мой телефон на базе Java едва имеет 2 ГБ, и, похоже, справляется. Может быть, я что-то здесь упускаю. Распространение для программ на Java заметно шире, чем для программ на C ++, и я не знаю почему.
Java-программы имеют большой объем файловой системы
Я чувствую, что слегка киваю, не соглашаясь с этим, в то время как я оглядываю комнату, чтобы увидеть, считает ли кто-то еще, что это правда.
Дело в том, что я понятия не имею, почему это звучит разумно для меня.
Здесь удобно использовать репозиторий пакетов Arch Linux, поскольку в нем указан установленный размер для каждого пакета. Мой старый друг Закрытие Компилятор составляет 19,7 МБ. Вот это да! Это много. Правильно? Ну, может и нет. Самым похожим проектом, о котором я могу подумать, является Babel , который компилирует последний ECMAScript в нечто более дружественное к браузеру, и оно все еще составляет 7,0 МБ. Закрывающий компилятор может делать большую часть того, что делает Babel, плюс он больше похож на традиционный компилятор, поэтому я не удивлен, что он больше — во всяком случае, я удивлен, что он всего в два раза больше. GCC , тем временем, составляет 116,1 МБ.
Это крайне ненадежный и ненаучный способ измерения размера программного обеспечения. Но достаточно того, что у меня уже есть серьезные сомнения по этому поводу. Заманчиво сравнивать некоторые из программ для настольных компьютеров из более ранних версий, но даже FreeMind и XMind — две программы Java, которые служат примерно одной цели — имеют очень разные установленные размеры 27 МБ и 138 МБ соответственно.
Я даже не могу вспомнить анекдот, который объяснил бы, почему я ожидал, что программное обеспечение Java будет большим. Интересно, это потому, что Java- апплеты были относительно большими, когда они были популярны — когда многие люди все еще использовали коммутируемый доступ.
Прежде чем я перестаю выбирать Closure Compiler, у меня есть еще одна интерпретация «следа файловой системы» — расположение исходных файлов . Основная часть исходного кода Closure находится в директории на пять уровней , что выглядит немного экстремально. Этот каталог содержит 347 файлов .java
Многие из этих файлов выглядят так, как будто они могут быть сгруппированы в разумные категории, но это не так.
Может быть, Закрытие является исключением. GitHub говорит мне, что самый популярный Java-проект — эластичный поиск , реальный код которого также скрыт на пять уровней. Я не вижу каталогов с таким большим количеством файлов, но каждый каталог, кажется, содержит еще десять, и я еще не нашел дно.
Просмотр исходного кода для любого из этих (по общему признанию) проектов кажется пугающим. Здесь есть определенное количество разрастания. Напротив, большинство проектов Python относительно компактны: несколько уровней в глубину, полдюжины файлов в ширину.
Я подозреваю, что это сводится к очень важному свойству Java: один файл может содержать только один (публичный) класс. Насколько я понимаю, в Java нет понятия экспорта; если у вас есть файл foo/Bar.class
Bar
Независимо от того, как вы хотите организовать свой код, насколько велики или малы ваши классы или сколько у вас их, вам нужен отдельный файл для каждого публичного класса. Правила разные, но это немного напоминает мне Perl. Вау, это странная вещь, чтобы сказать.
Сравните это с Python, который имеет довольно похожую иерархию пакетов. Файл foo/bar.py
foo.bar
foo.bar.Bar
Но foo.bar
модульным объектом, который содержит все, что определено в файле. Импорт похож на Java, но файлы в свободной форме. Один файл может содержать множество небольших классов, бесплатных функций, общедоступных систем и всего, что вам нужно. Файлы Python могут содержать целые идеи ; Файлы Java скованы тем, что, по вашему мнению, должно быть «классом».
Мне трудно представить, как я работаю над большим проектом с таким ограничением на один класс на файл. Создание нового класса (а не привязка к уже существующему) уже включает в себя некоторые трения; необходимость создания целого нового файла была бы огромным препятствием. Возможно, я бы хотел иметь как можно меньше классов, поэтому я едва ли ассоциирую Java с большими волосатыми классами. Больше вещей на класс означает меньше классов в целом — проблема решена!
Любопытно, что у Java есть способ эмулировать Python-подобные модули, но я никогда не видел и не слышал об его использовании. import static
Класс верхнего уровня будет тупым контейнером, похожим на модуль Python, и любая комбинация его статических потомков может быть импортирована любым другим кодом. Увы, если это так необычно, как кажется, возникшее замешательство среди других разработчиков Java, вероятно, сведет на нет преимущества.
Снова глядя наasticsearch, структура пакета не слишком отличается от того, как я мог бы организовать проект Python. Рассмотрим этот каталог analysis
, где многие файлы являются шаблонными классами не более, чем лицензия в верхней части файла. Это один пакет с множеством маленьких классов; они распространяются только на несколько файлов, потому что язык требует этого. Таким образом ,asticsearch — довольно аккуратный проект. Я даже нашел несколько каталогов, в которых был только один файл / класс, и это именно то, что я получал бы, если бы эмулировал модули Python с каталогами пакетов.
Разрастание файла кажется немного раздражающим с точки зрения разработки, но оно переплетено с довольно фундаментальным законом языка. Извините, Ява; ты проиграл этот раунд
Java имеет большую стандартную библиотеку
Это настоящая жалоба? Я не уверен. Он аналогичен использованию «раздутого» программного обеспечения для конечных пользователей, поэтому стоит посмотреть.
Стандартные библиотеки — сложный компромисс. Скромная стандартная библиотека C означает, что во многих проектах изобретаются одни и те же колеса, но язык остается более простым и более переносимым. С другой стороны, огромная стандартная библиотека Python очень удобна, но в ней накопилось множество странных вещей, таких как более дюжины модулей IRIX . Я предпочитаю стандартную библиотеку, которая хорошо дополняет базовый язык, хотя я все чаще нахожу, что надежный менеджер пакетов может быть намного приятнее, чем поставка кухонной раковины с самим языком.
Я не могу придумать какой-либо хороший способ измерить размер стандартной библиотеки, кроме размера на диске. Ниже приведены размеры некоторых языковых сред выполнения, которые я установил на свою машину, а также глобальные zsh, которые я использовал для их измерения. Мне кажется, что в Java, .NET и Python достаточно большие стандартные библиотеки; У Rust и Ruby более умеренные; и Perl довольно голый. С ничто.
- Mono 4.6: 43 МБ —
/usr/lib/mono/4.5/**/*.dll
- OpenJDK 7: 33 МБ —
/usr/lib/jvm/java-7-openjdk/jre/lib/rt.jar
- CPython 3.5: 27 МБ —
/usr/lib/python3.5/**/*.py~*site-packages*
- Perl 5.24: 17 МБ —
/usr/share/perl5/core_perl/**/*.p[ml]
- Ruby 2.3: 8,9 МБ —
/usr/lib/ruby/2.3.0/**/*.rb
- Rust 1.12: 4.9 МБ —
/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-*.so
- C: 2,0 МБ —
/usr/lib/libc-2.24.so
Ну, хм. Цвет меня слегка удивил.
По общему признанию, это ужасное сравнение. Стандартная библиотека Rust компилируется вплоть до машинного кода (что делает его меньше). Я предполагаю, что Mono и OpenJDK скомпилированы в байт-код. Библиотеки CPython, Perl и Ruby представляют собой несжатый исходный код (делает их больше), но исключают несколько бинарных компонентов (делают их меньше), но содержат большое количество встроенной документации (делает их больше), но написаны на более высоком уровне. Языки уровня (делая их меньше).
Позиция Perl заставляет меня еще больше усомниться в этой методологии. Все, что я могу на самом деле сделать вывод, это то, что стандартная библиотека Java несколько больше, чем библиотека Python, что кажется правильным — Java поставляется с вдвое большим количеством пакетов графического интерфейса, чем, например, Python. Я не вижу здесь сильных признаков того, что стандартная библиотека Java неуправляемо велика.
Счет пока что
По слухам, Java — неуклюжий зверь? Результаты смешанные. Я не могу придумать ни одной веской причины, по которой Java будет обвиняться в том, что он работает особенно медленно, особенно в мире, который все больше использует JavaScript, и это не соответствует моему недавнему опыту. Я предполагаю, что Java был первым широко распространенным языком, который использовал виртуальную машину, для этого потребовалось немало усилий, и первые впечатления остались навсегда.
С другой стороны, Java может потреблять больше памяти, чем я ожидал. У меня нет удовлетворительного объяснения, почему это так или почему на моем рабочем столе все намного хуже, чем на моем телефоне. Вполне возможно, что пара моих скудных данных просто плохая. Также возможно, что Java действительно является проблемой памяти, поэтому на Java написано не так много общедоступного программного обеспечения для настольных компьютеров, и я никогда не замечаю этого на своем телефоне, потому что многозадачность почти не так велика.
Я программист, но я не программист на Java , поэтому большая часть этого была с точки зрения конечного пользователя — где несколько других факторов способствуют несправедливому негативному восприятию Java. Java напоминает пользователям настольных компьютеров о себе только тогда, когда она делает что-то раздражающее, например, запускает сервис быстрого запуска при запуске (это все-таки вещь?) Или ошибки в обновлениях. Я кратко упомянул, что Swing торчит как больной большой палец, и программы, которые я пробовал, укрепили это впечатление: они используют неправильные цвета и шрифты, они по умолчанию используют собственный субпиксельный рендеринг шрифтов Java, который плохо кровоточит, и они делают странные вещи, такие как эмуляция Диалог выбора файлов Windows 95 в Linux. Я стону каждый раз, когда сталкиваюсь с программой на Swing, потому что знаю, что это будет неуклюже и неуклюже — и, поскольку программа написана так явно на Java, я ассоциирую «неуклюжую» с Java в целом.
Но Java имеет небольшое и сокращающееся присутствие на рабочем столе и исчезает из браузеров, поэтому, возможно, точка зрения конечного пользователя не имеет большого значения. Java все еще нелепо популярна на стороне сервера и почти исключительно работает на Android, и для этого должна быть веская причина. Я остаюсь скептиком, но любопытно. Во второй части мне нужно больше взглянуть на то, на что похожа Java.