20 лет назад 23 мая вышла первая версия Java (таймлайн 20-летней истории). Многие поехидничают на тему «инновационности» Java (на фоне того же C#) и медленного развития. Но, даже несмотря на все трудности, платформа развивается, к счастью. Взять хотя бы довольно внушительные изменения в Java 8, те же лямбды, которых так долго ждали.
Сегодня значительная часть серверного ПО написана на Java. Однако два десятка лет назад к языку программирования предъявлялись иные требования. Это должен был быть хороший универсальный язык программирования для десктопов.
Java появилась в чрезвычайно важный момент для истории программирования. До тех пор в разработке ПО царствовали три языка: Fortran в научных вычислениях, COBOL в бизнесе и C (С++ тогда только начинал распространяться) во всех остальных проявлениях коммерческого программирования.
Менее популярные языки заполняли узкие ниши: Ada (вооруженные силы), Pascal (любительское программирование и ПО для мелкого бизнеса), Smalltalk и Lisp (академические круги), Perl (системные администраторы) и т.д. Но основу составляла, конечно, большая тройка.
В последние годы Java стала использоваться и на мобильных платформах, благодаря Android. Жаль, правда, что нет возможности использовать Java 8.
Georges Saab, вице-президент Oracle по разработке Java Platform отметил:
«За 20 лет роста и развития Java стала одной из самых значимых и заслуживающих доверия технологий в отрасли. Те, кто выбрал Java, были многократно вознаграждены ростом производительности, масштабируемости, надежности, совместимости и функциональности. Экосистема Java предлагает превосходные библиотеки, фреймворки, среды разработки и ресурсы для программистов — от новичков до экспертов. Сама же технология Java разрабатывается прозрачно в сообществе OpenJDK Community. Мы рады вступить в следующее двадцатилетие эволюции Java, результаты которой не замедлят себя ждать благодаря значительному вкладу Oracle, а так же вкладу других участников сообщества».
В общем, поздравляю всех нас!
P.S. Не поленитесь посмотреть инфографику от ребят из JetBrains. Они так же скидку до конца месяца предоставляют в честь праздника.
Комментарии (55)
NonGrate
26.05.2015 11:33+2К счастью, лямбды можно использовать на Андроиде через Retrolambda бэкпорт лямбд, method references и try-with-resources, работает хорошо, конфликтов синтаксиса в иде нет.
А стримы можно использовать через Lightweight-Stream-API, но я его ещё не опробовал, поэтому не знаю, насколько хорош бэкпорт.
github.com/orfjackal/retrolambda
github.com/aNNiMON/Lightweight-Stream-API
QtRoS
26.05.2015 11:34-8Нет ну это все равно минутка юмора — «Java: 20 лет инноваций». Java, Карл! 20 лет инноваций!
vedenin1980
26.05.2015 11:55+4На самом деле, нет. Если рассматривать не только синтаксис языка Java (которые довольно консервативен), а вообще все open source библиотеки, фреймворки и программные решения в мире Java, то окажется что инноваций там очень много, одно перечисление инноваций открытых программных решений на основе одного только Hadoop'a займет несколько страниц.
QtRoS
26.05.2015 13:17+1Ну тема-то все-таки про сам язык, а не библиотеки, и я не хейтер языка, а говорю правду. Если бы я программировал на JS в качестве основного языка, я бы не стал писать о том, что в нем все понятно в плане конвертации типов и т.д. (вспоминаем известную табличку истинности сравнений и наследование на прототипах), если бы на C++, то признавал бы катастрофически быстрое изменение языка, за которым сложно успеть (в последнее время), а вот в случае java'ы — медлительность развития. Ну кто может не кривя душой сказать, что ожидание Java 7 ему показалось незаметным? Вот Вики на эту тему. Любите язык — пожалуйста, но умейте признавать недостатки (без молчаливых минусов в карму =\ ).
vedenin1980
26.05.2015 13:36+21) Кто сказал что тема только про язык, а не про всю платформу Java?
2) Библиотеки гугла и апатча или фреймворки вроде spring, hibernet, guava это давно уже де-факто опциональная часть языка от сторонних разработчиков, так как не требует ничего кроме пары строчек в pom'е и используются практически всеми,
3) Медленность развития это не только минус, но и плюс, так как в крупном enterprise важнее стабильность, чем синтактический сахар и фичи, благо его полно в сторонних библиотеках
4) Мне ожидание Java 7 показалось незаметных, так как во всем местах где я работал (а это крупные международные фирму) никак не слезут с Java 6, ибо legacy и enterprise,
5) ну и в конце концов, я не могу ставить минусы в карму (и если бы мог то все равно бы не ставил)vedenin1980
26.05.2015 14:02+4Посмотрел в профиль, как и ожидалось метки C#, .Net и не слова про Java. У программистов C# есть ряд устойчивых мифов про Java:
Дело в том что в развитии C# выбрали модель «добавить как можно больше фич и сахара как можно быстрее», в развитии Java придерживаются модели «каждая фича сначала обкатываются на open source библиотеках и только абсолютно нужное и проверенное попадает в сам язык». Для тех кто хочет много сахара в самом языке есть scala и kotlin совместимый с остальным кодом Java, тем кому нужны фичи есть немеренное кол-во open sourc'a (в том числе от крупнейших фирм, вроде гугла) на любую задачу. Поэтому программистам C# кажется что Java устарела, не понимая что синтаксис языка Java это даже не верхушка айсберга, а одна десятая (если не сотая) от реального мира Java (причем бесплатного, открытого и доступного простым добавлением пары строчек в конфиг сборки).Dywar
26.05.2015 14:29+3«Конфуцианцы и буддисты спорят друг с другом потому, что конфуцианцы не читают буддийских книг, а буддисты не читают конфуцианских книг. И те, и другие судят о том, чего они не знают.»
Чень Цзижу
Джон Скит в своей книги провел пару сравнений, условно.vedenin1980
26.05.2015 14:39+1Да, я не спорю про C# (хотя достаточно долго его изучал), я говорю только о том что знаю (Java). Если сказал что-то не так поправьте. Вообще я даже пытаться не буду спорить что Java лучше C#, это исключительно вкус фломастеров и бессмысленый холивар, но лично мне больше нравиться философия Java, чем C#.
Suvitruf Автор
26.05.2015 14:42+1Ух, ветка куда-то не туда ушла. Изначально же спор возник на почве «Java — это только язык» vs «Java — это платформа» )
Nagg
26.05.2015 19:02+1немножко добавлю холивара про фичи языка — полгода назад стал активно писать проекты под Android на java (фактически перешел на нее с C#) и есть пару веще с которыми мне сейчас тяжело мириться:
1) цирк с примитивными типами long--Long с невозможностью юзать первые в генериках (уж молчу о том, что нельзя писать свои кастомные Value Types)
2) отсутсвие var (или как в плюсах — auto). хоть за сниппет .var спасибо IDE. но все равно не то. сравните:
FooFactoryFactory foo = new FooFactoryFactory(); vs: var foo = new FooFactoryFactory();
3) лямбды и Stream — очень рад что это появилось в яве, хоть до C# LINQ не дотягивает отсутсвием возможности разбора дерева выражения. Ну и через костыли в принципе подключаемо к андроиду.
4) ну и конечно же async/await
представьте что вам нужно послать ассинхронный реквест и по приходу ответа обновить текст на UI:
android java:
client.sendRequest(request, new ResponseCallback() { @Override public void onResult(Object object) { currentActivity.runOnUiThread(new Runnable() { @Override public void run() { currentActivity.title.setText("done!"); } }); } });
android C#:
var responseObj = await SendRequest(request); //runOnUiThread не нужен т.к. await вернет первоначальный контекст currentActivity.title.Text = "done"
Но это сравнивая решения в лоб без библиотек типа robospice, javaRX (за которую большое спасибо)TimReset
26.05.2015 19:25+1Интересное сравнение!
1) Да есть этот минус. Под него даже костыли делали в Java 8 в Stream API — были свои stream для примитивов.
2) Насколько я понимаю идеологию Java, это никогда не введут — в Java в почёте строгая типизация. А в var не будет работать, насколько я понимаю.
3) По этому пункту ничего сказать не могу — сам Stream API не много пользовался. Скорее всего это сможет прокомментировать lany
4) Как вы сами сказали, сравнивали без javaRX — с лямбдами это было бы менее многословно.
Добавлю тут erase generic — если нужно знать тип переменной, то приходится помимо неё так же и её класс передавать, что немного увеличивает код. Хотя type safe остаётся :)
А вообще, вы пробовали Kotlin? e.g. habrahabr.ru/post/258683 Насколько я понимаю, это то что вам нужно.Nagg
26.05.2015 19:36+12) — var в C# не ослабляет типизацию. это автовычисление типа по выражению справа.
4) да, сам подумал так, но тогда могу усложнить пример — надо выполнить 3 разных запроса один за одним обновляя текст на UI:
await client.SendRequest1(request1); currentActivity.title.Text = "1/3"; await client.SendRequest2(request2); currentActivity.title.Text = "2/3"; await client.SendRequest1(request3); currentActivity.title.Text = "3/3";
vs:
client.sendRequest1(request1, o -> currentActivity.runOnUiThread(() -> { currentActivity.title.setText("1/3"); client.sendRequest2(request2, o -> currentActivity.runOnUiThread(() -> { currentActivity.title.setText("2/3"); client.sendRequest3(request3, o -> currentActivity.runOnUiThread(() -> { currentActivity.title.setText("3/3"); })); })) }));
писал в блокноте поэтому уверен что в java напутал в конце со скобками ибо нечитаемо.
зы: пробовал. на котлин вся надежда.TimReset
26.05.2015 22:22+12. Собственно ниже ответили на счёт var — List list = new ArrayList не аналогично var list = new ArrayList, а если учесть что интерфейс предпочтительно перед реализацией, то это в общем спорная фича.
Nagg
26.05.2015 22:26Для этого кейса да. но в большинстве других где тип слева такой же как справа var необходим. особенно если название типа очень большое, к примеру:
GroupConversation.GroupConversationParticipant participant = new GroupConversation.GroupConversationParticipant();
если мы не приводим к базовому/интерфейсу — эта копипаста не нужна и должна быть заменена на
var participant = new GroupConversation.GroupConversationParticipant();
lany
27.05.2015 04:28Пример искусственный. Импортируйте вложенный класс
GroupConversationParticipant
, получите
GroupConversationParticipant participant = new GroupConversationParticipant();
В современном коде переменные вообще не нужны, каждый метод должен состоять из одного предложенияreturn
:D
int19h
27.05.2015 03:55+1Для локальной переменной нет никакого смысла ограничивать её тип интерфейсом — она не более чем деталь реализации метода. Интерфейсы имеет смысл использовать на границе API, но как раз там var в C# недоступен.
lany
27.05.2015 04:30Почему же нет смысла? Без этого будут лишние головняки при рефакторинге, если метод длиннее трёх строчек. В какой-нибудь ветке вы в будущем захотите присвоить туда
Collections.singletonList
, и всё равно придётся менять тип.int19h
27.05.2015 04:38А в чем проблема поменять тип, если это вдруг понадобится? Ну будет дифф не на две строки, а на три.
(Как показывает практика, в 99% случаев — не понадобится, и по умолчанию имхо стоит исходить из этого.)lany
27.05.2015 05:31+1Точно так же никакой проблемы нет в том, чтобы сразу использовать интерфейс. Это нулевые затраты.
Всё становится сложнее, когда программист автоматом добавляет return из метода, IDE выводит возвращаемый тип из типа переменной, программист не парится (приватный метод же, деталь реализации) и присваивает снаружи тоже в ArrayList. Потом всё это прорастает через цепочку методов (хорошо, если все приватные) и кучу переменных (а то и каких-нибудьMap<String, ArrayList<String>>
), и одно исправление во внутреннем методе требует замены кучи типов. Гораздо проще всегда по умолчанию использовать интерфейсы и не думать об этом. Конкретный тип может потребоваться, только в очень специфических случаях (например, анализ дампа памяти показал, чтоArrayList.trimToSize
вызвать нелишне).int19h
27.05.2015 06:00+1>> Точно так же никакой проблемы нет в том, чтобы сразу использовать интерфейс. Это нулевые затраты.
В плане написания — возможно. В плане чтения, особенно когда активно используются дженерики, и там еще что-то вложенное — var проще.
>> Всё становится сложнее, когда программист автоматом добавляет return из метода, IDE выводит возвращаемый тип из типа переменной
А вот тут я уже замечу, что нехорошим в данном случае является именно автовывод типа возврата. Границы метода — они неспроста.
TimReset
27.05.2015 11:124. В таком ключе await явно выигрывает, да. Вообще идея интересная — внести в синтаксис поддержку многопоточности. Может в дальнейшем это сделают — всё таки направление в развитии в сторону многопоточности явно прослеживается, так может и в синтаксис внесут.
dougrinch
26.05.2015 19:46+4*я всегда буду обновлять комментарии*, хотя ответ получился немного о другом, так что все ок
Позволю себе ответить за автора оригинального комментария.
1. Что значит «были»? Они все еще есть.
2. var к строгой типизации не имеет ни малейшего отношения. После type inference (а в восьмерке он довольно хороший) будет точный тип. Т.е. это фича исключительно компилятора. Тут есть другой момент: я не могу заменить на var объявление
List<String> list = new ArrayList<String>;
т.к. переменная станет типа ArrayList, что не очень хорошо.
3. А тут и нечего говорить. Действительно нельзя. Лябда — это просто специфический синтаксис для создания реализации интерфейса. Если уж очень нужно, то можно вытащить байткод метода, в который скомпилировалось тело лямбды (что само по себе не совсем тривиальная задача) и уже как-то анализировать его. Но это скорее грязные хаки, нежели «возможность разбора дерева выражения».
4. Тут не в лябмдах дело. rx — скорее другой подход к проектированию. Async/await же позволяет писать плоский код, вместо вложенных коллбеков. И это прекрасно.sAntee
27.05.2015 02:25+42. объект в переменной как был ArrayList, так и останется. Что плохого в том что тип переменной это отражает? Если потом этот list возвращается как List или передается в функцию которая ждет интерфейс — ничего не изменится, наружу точно так же и будут торчать интерфейсы… Единственный случай, который в голову приходит, это если в эту же перменную надо будет позже положить другой объект, который не ArrayList, а List. Нууу, explicitly typed variables никто не отменял.
lany
26.05.2015 20:46+1А что я могу прокомментировать? Ну да, разбор синтаксического дерева в том виде, как это сделано в LINQ, отсутствует в Java. Мне вообще нравятся языки, где разработчики думают не только над тем, какую бы ещё фичу добавить, но и над тем, какие фичи не добавлять. Получается не разрозненное месиво функционала, а концептуально выдержанный язык.
Nagg
26.05.2015 22:36+1Если вы понимаете что это такое, то наверняка знаете какой профит это дает. Была бы такая фича — была бы возможность в java написать такой код
persons.stream().filter(p -> p.getAge() > 18).limit(100).collect(Collectors.toList());
который бы при выполнении сконвертился бы в SQL
"select top(100) * from persons where age > 18"
и вернул объекты из бд. Но в целом согласен — фичи надо вводить с умомlany
27.05.2015 04:40+2Да, естественно, я это понимаю. На мой взгляд это слишком ненужная абстракция, которая легко протекает. Если я в фильтре вызову Java-метод или обращусь к другой структуре данных (скажем
.filter(mySet::contains)
)? Всё равно придётся помнить, что можно делать и чего нельзя. Java очень консервативна в плане адаптации синтаксиса под конкретные частные задачи. Тут ни перегрузки операторов, ни даже поддержки регекспов на уровне /синтаксиса/. Зато читать код и анализировать сторонними тулзами гораздо легче, чем разбираться, SQL-запрос тут под капотом или нет.Nagg
27.05.2015 12:15+2Да, протекает. Но не так уж и легко — в EF (и даже в дотнетовской реализации Hibernate) всё нужное интерпретируемо в SQL даже если вы в фильтре вызовете contains на какой-нибудь локальный лист. Давно не сталкивался с ошибками того, что я что-то не то сделал в лямбдах в linq. Раньше в спорах java vs C# в ход шел козырь кроссплатформенность. Сейчас он как-то стал неактуален с xamarin. И пошёл новый козырь: у нас фичи продумываются столетиями и всё идеально, а у вас бардак :-).
lany
27.05.2015 12:22+3Да причём тут споры и козыри? Пишите на чём нравится. Я не пытаюсь вас убедить, что Java лучше шарпа. Это прекрасно, что в мире много языков с разной философией. Зачем делать из Java ещё один C#, если C# уже есть? Зачем делать из Java Скалу или Котлин, если они уже есть? Java — это Java.
vedenin1980
27.05.2015 12:27+2Не, главный козырь, в том что куча проверенного и оттестированого open sourc'a на любые цели, которым занимаются в том числе и крупнейшие компании, в платформе Java для программистов важнее любого синтактического сахара и фич других языков. Но вообще мерятся ху… языками занятие бессмысленное, пока есть конкуренция между языками они развиваются и это замечательно. :)
kivsiak
26.05.2015 22:35Я вот тоже так думал. Сам старый явист, но пришлось пописать гуйню на C#. Поначалу протащился потом стало грустно возращаться на Java под андроид c его java 6+++. Но retrolambada, javaRX, kotlin… ну че мне в этом c#? А тут еще и scala есть для сервесайда. И все это совместимо во все стороны. И чувствую жизнь то налаживается Ж)
senia
27.05.2015 11:29Если хочется именно фич, что достаточно добавить в проект scala и можно получить все нужные фичи.
1) Примитивные типы спрятаны. Есть даже ограниченная возможность писать свои value types (только на основе существующих примитивов).
2) val/var. val в C# мне не хватало.
3) Разбор дерева на этапе компиляции. См. slick. На самом деле механизм мощнее, чем в C# — вот пример от меня.
4) Есть.
int19h
27.05.2015 03:53>> в развитии C# выбрали модель «добавить как можно больше фич и сахара как можно быстрее»,
Это в равной степени миф. Я вам советую почитать записи в блоге Эрика Липперта про дизайн языковых фич, и design meeting notes из страницы Roslyn на GitHub. Там можно увидеть, насколько нещадно на самом деле режутся списки предлагаемых фич.
intet
27.05.2015 08:33+1Есть вещи которые трудно исправить сторонними библиотеками. Например половинчатая система дженериков.
C# очень быстро развивался, так как просто позволял себе ломать обратную совместимость и быстро выкинул из себя не очень удобные решения. А вот java тянет с собой старый код, а вместе и кучу проблем.vedenin1980
27.05.2015 08:45К сожалению это так, с другой стороны иначе legacy код никогда не получилось бы перевести на новые версии Java. Это даже сейчас не так просто перейти с 6 на 7 или 8, а если бы сломали обратную совместимость… Для тех кто хочет Java без обратной совместимости есть Scala и Kotlin.
intet
27.05.2015 08:57+1В scala ровно те же проблемы с дженериками, что и java. И scala используется гораздо реже.
Учитывая как бизнес быстро переходит хотя бы с 6 на 7, то ломание совместимости не очень бы сильно и замедлило динамику. Так как старые проекты очень редко переводят на новую платформу и основной приток идет за счет новых проектов.
TimReset
26.05.2015 18:33+3we need to go deeper — в Java 7 были большие изменения в JVM: быстрый гуглёж habrahabr.ru/post/125202 плюс добавление NIO2. А так язык, да, не сильно изменился — try-with-resource, multi-catching и swich-case-string. Вообще JVM с каждой версией сильно меняется, без изменения самого языка. Пруфы — выступления на JPoint разработчиков JVM.
P.S. Спорить не сильно хочется, но, надёюсь, мой комментарий сделай вас лучше, как программиста, и вы будете различать синтаксис и платформу. Собственно, вам уже выше объяснили, но дополню их комментарии.lany
27.05.2015 06:50+2«Самого главного глазами не увидишь». Собственно самая главная фича платформы Java 7 — это invokedynamic. Хотя в самом языке Java она в семёрке ещё не использовалась, но дала толчок для дальнейшего развития. JRuby переписали на invokedynamic, он стал в разы быстрее. Стал возможен проект nashorn. Ну и быстрые и лёгкие лямбды в восьмёрке.
TimReset
27.05.2015 11:07Точно! Я просто забыл, когда он появился — думал, что в 6-ке и не стал писать. Позор на мои седины :)
semmaxim
26.05.2015 14:32По-моему, уже стоит разделять java, jvm и около-jvm-языки-и-библиотеки.
kivsiak
26.05.2015 22:38+1Не стоит. В этом сила java как платформы. Есть jvm — как машина. Есть Java — яызык как некое универсальное среднее. Есть либы и jvm based языки которые вносят огромную гибкость в Java как платфрму
Duduka
26.05.2015 14:50-8? "...Java появилась в чрезвычайно важный момент для истории программирования. До тех пор в разработке ПО царствовали три языка: Fortran в научных вычислениях, COBOL в бизнесе и C (С++ тогда только начинал распространяться) во всех остальных проявлениях коммерческого программирования..."? Правда?! Фортраныч остался на PDP-11 и ЕС-серии, и в 90х они были только в музеях и «очень инновационных» вузах. Да, машинки были но, на фортране мы писали лишь для академии наук, на производстве — паскаль, мампс. С появлением персоналок — Turbo Pascal, DBase(Paradox, Clipper, FoxPro), Turbo C/ MS C. To что кто-то писал на фортране и позже- это возможно(интельский, вэтком...), но по масштабам запрса… На COBOLе писали, по ходу, только в штатах, у них оплата была за количество строк кода и по этому тексты(простыни) были очень кстати.
А момент стал «чрезвычайно важным» — титаническими усилиями MS подмять программиское сообщество под себя, и посадись энтерпрайсь на офис важнейшей компании.
AlexWinner
27.05.2015 08:07+1> В последние годы Java стала использоваться и на мобильных платформах, благодаря Android.
В последние? А J2ME?
ncix
27.05.2015 09:48Java появилась в чрезвычайно важный момент для истории программирования. До тех пор в разработке ПО царствовали три языка: Fortran в научных вычислениях, COBOL в бизнесе и C (С++ тогда только начинал распространяться) во всех остальных проявлениях коммерческого программирования.
Что за чушь? Какой нафиг COBOL и Fortran в 1995 году? В то время по планете яростно шагал Delphi, был на подходе C++ Builder. Корпоративный рынок уже принадлежал Microsoft а с ним и MS Visual C++ c MFC впридачу.
OberonForGood
The Oberon language — together with the Oberon System — was designed and implemented
by Prof. Niklaus Wirth and Prof. Jrg Gutknecht at ETH Zrich from 1985 to 1987. Since
then it has been used intensively for teaching but also for projects at ETH and elsewhere.
Нет, действительно скотина: ворвался в дом, наследил, испортил [распрямляя кочергу] хо… ро… шую вещь!.. (с) Ш. Холмс