как-то пару лет назад в школу приходили тесты КЕГЭ на java. вот тогда я оценил java, т.к. смог запустить на линуксе. но подрядчик этот, видимо, свернул активность и теперь все приходит windows-only. я это к чему?
в школах отменили пробные тесты из-за отсутствия бумаги. java как никогда актуальна.
Интересно, а кто-то вообще не-LTS версиями всерьёз пользуется? Ну там проекты какие пилит? В голову только обкатка новых GC приходит, для последующего мигрирования на новую LTS.
Ну вот сидишь ты на не-lts, всё пучком. Выходит новая не-lts версия, а у тебя проект на ней нормально не работает, зависимости не поддерживают новую яву или ещё какой сюрприз. А старая версия перестаёт получать обновления и ты сидишь хрен знает сколько времени на неподдерживаемой версии пока не пофиксишь.
Хотя если у тебя хипстоспринг с микросервисами, то может и похер.
Технические проблемы в экосистеме бывают только считаные месяцы после релиза. Когда системообразующие библиотеки типа Спринга или Груви должны перейти на новую версию
Потом уже дальше остаются только проблемы в твоём проекте
Если у тебя зависимости настроены так погано, что XML-ку с ними нужно править «черт знает сколько времени», то ура - у тебя есть куда большие проблемы, чем новая версия джавы! Это хороший индикатор того, что какой-то проект стал настолько легаси, что развалится от дуновения ветерка
бывают ситуации, когда у тебя банковское мега-легаси, которое живёт на терабайте оперативки и жрёт 64 головы процессора, и потом оно начало каждые полчаса падать в корку. И тут надо бы пойти к поддержке, но поддержка по LTS даст результат быстрее (возможно, даже дешевле), чем поддержка по самой свежей версии.
Нереальный сценарий. Все релизы поддерживаются больше года. Если библиотеку не пофиксили за год, значит она сдохла и пора от неё избавляться. А вообще несовместимости с новыми версиями жавы это большая редкость. Самое главное, чтобы спринг совместимость подтвердил. Остальное всегда работает.
знаю о проблемах в lombok, ASM, ByteBuddy и прочих генераторов байткода. Groovy в своё время очень долго переползал на 11.
Hadoop и прочая Big Data инфраструктура вокруг него до сих пор нормально работает только на восьмёрке.
дико смешно, например, что первый баг запуска Хадупа на 11 в том, что в каком-то месте в статическом инициализаторе проверяется версия джавы и там берется lastIndexOf от версии джавы («1.8») чтобы проверить мажорную часть версии. А в цифре 11 нет точки, и весь хадуп падает прям на инициализации классов ))
Если в следующей версии баг, а в предыдущей бага нет, конечно обновляться не надо, надо зарепортить баг и подождать исправления. Но это к LTS вообще отношения не имеет, это к любой зависимости относится. И LTS может выйти с багом и в LTS может прилететь баг.
Да, это бывает, но поэтому я и говорю про спринг. Когда спринг обновился и верифицировал свою работу, значит, что все эти asm-ы уже работают нормально, т.к. спринг на них завязан сильно.
Про хадуп ничего не знаю, но вроде это же отдельная программа по сути.
Я пользуюсь. Не понимаю этого фапанья на LTS. Какая разница, LTS, не LTS. Лишь бы спринг работал.
А что ты делаешь, когда не-LTS уже не поддерживается Ораклом, а новая версия (не важно, LTS/не-LTS) ещё не поддерживается спрингом или грейдлом или ещё чем? LTS интересна именно длительностью своей поддержки, в том числе и обновлений безопасности.
Вроде бы уже научились сохранять результат нативной компиляции от JIT, а это тогда зачем? Ведь одно из преимуществ первого в том, что там динамическая оптимизация, которая может оптимизировать лучше статической в каком нибудь C++.
Интересного ожидается много. Но пока ожидается.
Какое-то оно малоинтересное получается, в итоге. Лучше бы довели до ума модули и дженерики. Например коллизии в версиях транзитивных зависимостей до сих пор не имеют нормального решения, а лишь те или иные костыли, о которых постоянно плачится Барух на Jug.ru Нормальные модули могли бы решить эту проблему.
Легковесные потоки, как в erlang/golang, чтобы можно было писать блокирующий код, и при этом держать миллион соединений без миллиона ОС-потоков.
Народ ещё с рекордами не обжился, а тут это.
По сути это будет оптимизация. К примеру Optional будет не отдельным объектом в куче, то же к Integer и тд. Если я правильно понял, там особо ничего и делать не надо, оно само заработает. Ну для своих классов надо будет включить, если у тебя есть классы-обёртки, но и без этого профит ожидается.
Вроде бы уже научились сохранять результат нативной компиляции от JIT, а это тогда зачем?
Чтобы получить app.exe без JVM, который будет моментально стартовать и жрать меньше памяти.
Ведь одно из преимуществ первого в том, что там динамическая оптимизация, которая может оптимизировать лучше статической в каком нибудь C++.
Это опциональный режим. Определённая популярность GraalVM говорит о том, что народу это интересно.
Какое-то оно малоинтересное получается, в итоге. Лучше бы довели до ума модули и дженерики. Например коллизии в версиях транзитивных зависимостей до сих пор не имеют нормального решения, а лишь те или иные костыли, о которых постоянно плачится Барух на Jug.ru Нормальные модули могли бы решить эту проблему.
Вряд ли это когда-нибудь изменится. Да и вряд ли это кому-то особо надо. Меня текущие генерики устраивают более чем, к примеру. С версиями - в npm превращать жаву - я против.
Меня текущие генерики устраивают более чем, к примеру.
<T> List<T> getObject(Class<T> cl) {
return new ArrayList<>();
}
Как заставить этот метод вернуть List<Map<String, Integer>>?
С версиями - в npm превращать жаву - я против.
Версии зависимостей уже и так есть, но использовать более одной версии в одном classpath или modulepath невозможно. Ну разве что с костылями, как например выдумывать новое название пакеджа (как это правильно по-русски назвать?), как например это делают в некоторых библиотеках от Apache.
Если скажешь, зачем тебе такой метод, можно попробовать по-другому сделать.
Версии зависимостей уже и так есть, но использовать более одной версии в одном classpath или modulepath невозможно. Ну разве что с костылями, как например выдумывать новое название пакеджа (как это правильно по-русски назвать?), как например это делают в некоторых библиотеках от Apache.
Я и говорю - я против того, чтобы превращать жаву в npm. Ибо тогда там, где сейчас 200 мегабайтов зависимостей, их будет 2 гигабайта. И запускаться простое приложение будет не 5 секунд, а 20 секунд, ибо все эти гигабайты класс-файлов надо будет открыть, прочитать с диска, распарсить, верифицировать.
Не очень понял, зачем ты туда вообще передаёшь параметр cl. Но как минимум три способа
И все они костыльные, с предупреждением «unchecked cast».
Я и говорю - я против того, чтобы превращать жаву в npm. Ибо тогда там, где сейчас 200 мегабайтов зависимостей, их будет 2 гигабайта.
Коллизии в транзитивных зависимостях - вещь не частая, поэтому не будет там такого. Но вместе с тем, когда это всё таки случается и решается методом «должен остаться только один» есть немалый шанс получить проблемы.
И все они костыльные, с предупреждением «unchecked cast».
Ну подавить это предупреждение недолго. А так - на такое ТЗ результат ХЗ. Class<?> не предназначен для такого и нет смысла его так использовать.
Коллизии в транзитивных зависимостях - вещь не частая, поэтому не будет там такого. Но вместе с тем, когда это всё таки случается и решается методом «должен остаться только один» есть немалый шанс получить проблемы.
А с методом включения нескольких классов в один класслоадер появляется прям очень много других весёлых проблем.
На всякий случай сообщу, что если очень хочется, то иерархические класслоадеры в жаве существуют фиг знает сколько десятков лет и никакой принципиальной проблемы наколхозить такую систему нет. И модули тут не нужны.
А всё из-за этого самого type erasure в дженериках.
Class<?> не предназначен для такого и нет смысла его так использовать.
Не Class<?>, а Class<T>.
А с методом включения нескольких классов в один класслоадер появляется прям очень много других весёлых проблем.
Речь о нескольких версиях одного и того же класса и разумеется в разных класслоадерах.
На всякий случай сообщу, что если очень хочется, то иерархические класслоадеры в жаве существуют фиг знает сколько десятков лет и никакой принципиальной проблемы наколхозить такую систему нет. И модули тут не нужны.
Как раз таки нужны, потому что они предоставляют изоляцию. Более того, изначально они именно такими, многоверсионным, и задумывались, но идею сначала слишком усложнили, а затем, столкнувшись с проблемой разрешения версий во время загрузки решили от неё вовсе отказаться. При этом некоторые атавизмы изначальной идеи там всё таки остались - версии у модулей есть, но указать их в зависимостях модуля или загрузить больше одной в modulepath нельзя. Вот послушай одного из авторов этого безобразия и о том, как он предлагает извращаться чтобы как-то побороть:
В конце он просит публику написать вокруг всего этого какой-то фреймворк, который сам не осилил, чтобы можно было пользоваться не только на лекциях для гиков, но и в реальном продакшене.
Ну если ты относишься к предупреждениям, как к религиозной анафеме, то да. А так - предупреждения это предупреждения, ничего больше. Ты пытаешься поломать систему типов жавы, она тебе даёт это сделать, но с предупреждениями. Если уверен, что ты умней компилятора жавы - вперёд и с песней.
А всё из-за этого самого type erasure в дженериках.
Нет, всё из-за того, что ты зачем-то передаёшь в метод неиспользуемую переменную.
В конце он просит публику написать вокруг всего этого какой-то фреймворк, который сам не осилил, чтобы можно было пользоваться не только на лекциях для гиков, но и в реальном продакшене.
Я в курсе, но я уже сказал, что против этого. Ибо будут абузить и будет у каждой зависимости в итоге свой класслоадер и будет logback в 50 версиях лежать, вместе с commons-logging-ом 1989 года.
в смысле да, сдача (пробного. какой был настоящий, не знаю) экзамена в электронном виде. ставится софт для проведения, а в нужный момент приходят криптоключи и загружаются данные самого экзамена.
я тогда добровольно в школе два класса с убунту поддерживал.
Ну если ты относишься к предупреждениям, как к религиозной анафеме, то да. А так - предупреждения это предупреждения, ничего больше. Ты пытаешься поломать систему типов жавы, она тебе даёт это сделать, но с предупреждениями. Если уверен, что ты умней компилятора жавы - вперёд и с песней.
В том-то и дело, что ничего ломать я даже не собирался, оно там уже сломано из-за type erasure и именно поэтому что-то вроде Map<String, Integer>.class не поддерживается, а поддерживается лишь просто Map.class
Нет, всё из-за того, что ты зачем-то передаёшь в метод неиспользуемую переменную.
Используемую. Именно она определяет тип T
Я в курсе, но я уже сказал, что против этого. Ибо будут абузить и будет у каждой зависимости в итоге свой класслоадер и будет logback в 50 версиях лежать, вместе с commons-logging-ом 1989 года.
Совсем необязательно заводить отдельный загрузчик классов под каждый отдельный модуль. Можно сделать умнее и скорее всего с прокси классами, у которых один загрузчик. Но если текущую реализацию модулей пилили целых 10 лет, то это вообще непонятно когда может появиться, если вообще.
Это ведь просто демонстрационный код. Класс можно использовать для создания его экземпляров, которые затем попадут в возвращаемый лист. Зачем ты придираешься к мелочам?
Почему ты решаешь за меня как создавать экземпляры класса? Логика создания этих экземпляров может быть более сложной, у getObject() может быть масса дополнительных аргументов. К тому же дженерики с их «забыванием типов» появились гораздо раньше лямд и Supplier. Вместо того, чтобы избавиться от глупого type erasure ты предлагаешь очередной костыль.
Type erasure не глупый, а нормальный, со своими плюсами. Лямбды в данном случае не обязательны, ты ровно то же мог соорудить в Java 5 на анонимных классах. Ты просто придумал надуманный пример и упёрся в него, вместо того, чтобы переписать код на нормальный.
Type erasure не глупый, а нормальный, со своими плюсами.
Если ты поинтересуешься историей создания дженериков в Java, то узнаешь, что это было компромисным решением в связи с нехваткой времени на более правильную реализацию. На сколько я знаю в C# (наследнике Java) type erasure нет.
Лямбды в данном случае не обязательны, ты ровно то же мог соорудить в Java 5 на анонимных классах.
И это было бы ровно таким же костылём.
Ты просто придумал надуманный пример и упёрся в него, вместо того, чтобы переписать код на нормальный.
Ну ты ещё скажи, что использовать рефлексию - ненормально.
Если ты поинтересуешься историей создания дженериков в Java, то узнаешь, что это было компромисным решением в связи с нехваткой времени на более правильную реализацию. На сколько я знаю в C# (наследнике Java) type erasure нет.
Ещё раз повторю, это не компромиссное решение, это альтернативное решение, со своими плюсами и минусами. К примеру без type erasure тебе придётся создавать новый инстанс Class на каждое использованное сочетание типов, что раздует permgen.
И это было бы ровно таким же костылём.
Ничего костыльного тут нет, это самый нормальный вариант.
Ну ты ещё скажи, что использовать рефлексию - ненормально.
Ненормально её использовать, когда есть нормальные альтернативы. Иногда - нормально. В данном случае это костыль.
Ещё раз повторю, это не компромиссное решение, это альтернативное решение, со своими плюсами и минусами. К примеру без type erasure тебе придётся создавать новый инстанс Class на каждое использованное сочетание типов, что раздует permgen.
Этих сочетаний не так много, чтобы прямо «раздуть permgen». С тем же успехом ты мог бы пожаловаться на интерфейсы. Можно ведь и без них и permgen похудеет.
Ненормально её использовать, когда есть нормальные альтернативы. Иногда - нормально. В данном случае это костыль.
В данном случе это всего лишь пример, а не код из продакшена.
только не в связи с нехваткой времени, этого добра у Оракла - бесконечно. А в связи с тем, что нельзя тормозить развитие экосистемы. Если бы появились non-erasure generics, то пришлось бы переписывать всю экосистему несколько лет. А это помешало бы победному шествию джавы и тому, что вот сейчас джава - один из самых важных языков в мире
Этих сочетаний не так много, чтобы прямо «раздуть permgen».
до тех пор, пока ты не начинаешь программировать в функциональном стиле, и заниматься функциональной кодогенерацией, и у тебя в тип перемещается значительная часть информации
помню лютые боли в рассылочке тех времен, когда Scala умела компилироваться в байткод .NET, и в JVM всё реализовывалось легко и с полпинка, а в CLR приходилось мутить ужасы с изобретением erasure поверх non-erasure generics. В конце концов, дотнетовский бэкенд тупо дропнули.
С тем же успехом ты мог бы пожаловаться на интерфейсы. Можно ведь и без них и permgen похудеет.
вообще-то, нефигово на них бы и пожаловаться. Мне сейчас лень писать демку, может кто сразу знает - умеет ли класс наследовать более 255 интерфейсов одновременно, и выцепляются ли они все через рефлекшен апи? А такое легко может возникать при кодогенерации, когода ты используешь список отрефлексированных интерфейсов как маркерный интерфейс, например при написании плагинов
Если ты поинтересуешься историей создания дженериков в Java, то узнаешь, что это было компромисным решением в связи с нехваткой времени на более правильную реализацию.
Тут уже правильно сказали что времени было много. Но причина была в миграционной совместимости, т.е. добавление дженериков никаких проблем не создавало со старым кодом и старыми сторонними либами. Появление дженериков не заставляло «обновлять мир», во многих случаях можно было просто поменять версию JRE/JDK и все продолжало работать по старому. Код постепенно актуализировался и либы обновлялись, все происходило плавно.
А у C# было несколько версий Runtimе в поставке, в то время там за совместимость не боролись.