Релиз Java 8 передвинут на март 2014 года

    Главный архитектор платформы Java Марк Рейнхольд сегодня объявил в своём блоге, что выпуск Java 8 переехал с сентября этого года на март следующего. В последнее время много сил инженеров Oracle было переброшено на то, чтобы сделать платформу Java более безопасной. Люди брались не из ниоткуда, а перебрасывались с других фич, в частности, с лямбды. Поэтому процесс разработки новых фич в Java 8 в последнее время шёл медленнее ожидаемого, и дата релиза уехала на полгода.

    Марк задаёт вопрос: а какие вообще были варианты у ребят из Oracle? Во-первых, можно было просто выкинуть лямбды из релиза. В этом случае времени на релиз должно было бы хватить, но лямбды уехали куда-то примерно на 2016 год, что не очень здорово. Второй вариант — это выпустить местами кастрированную, местами недотестированную и в целом сыроватую лямбду и получить пачку возможных граблей. Плюс в обоих этих вариантах не очень много времени на фиксинг секьюрити-багов, которым в последнее время Oracle уделяет повышенное внимание. Третий вариант, на котором и остановились дядьки из Oracle — это подвинуть релиз на полгода.Это позволит, во-первых, лучше протестировать новые фичи (прежде всего, лямбду) и собрать больше фидбэка от юзеров, а во-вторых, сделать Java более безопасной, закрыв некоторое количество потенциальных уязвимостей за это время.

    Наверняка что-то более подробное на тему переноса релиза на март 2014 года мы услышим уже в ближайший вторник в Москве на конференции JavaOne Russia 2013. Если у вас есть какие-то вопросы по переносу релиза — задавайте их в каментах к этому посту, мы с другими инженерами Oracle попробуем на них ответить.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 103

      +2
      лучше бы структуры и unsigned добавили как в шарпе, ей богу. Без лямбд можо прожить
        0
        И memory pinning для JNI!
          +6
          Ну учитывая то, сколько они делали поддержку строк в switch, структуры тоже будут очень не скоро.
          • UFO just landed and posted this here
              +5
              Чтобы сборщик мусора отдыхал :)
              • UFO just landed and posted this here
                  0
                  Структуры располагаются в стеке потока, а не в куче, в следствии чего не требуется освобождение памяти сборщиком мусора.
                  В Java есть примитивы(byte, short, int, float,...) это аналоги структур в .NET (они располагаются в стеке). Однако нет возможности создать пользовательский тип который бы располагался в стеке.
                  • UFO just landed and posted this here
                      +2
                      В C# от такой возможности больше пользы, чем проблем. Там структуры — это очень редко используемая штука, но иногда они могут очень сильно поднять производительность.
                      • UFO just landed and posted this here
                          –2
                          По не воле вспомнилось высказывание: «Если бы в Java действительно работала сборка мусора, большинство программ бы удаляли сами себя при первом же запуске».
                      +3
                      Еще массивы структур располагаются в памяти одним блоком, а не массивом ссылок на объекты в куче. В некоторых случаях это принципиально.
                      • UFO just landed and posted this here
                        +4
                        вообще-то структуры не всегда в стеке располагаются. А вот эскейп анализ и прочие оптимизации в случаи доработки обеспечат такой же эффект абсолютно прозрачно. К тому же на минорных сборках GC не напрягается.
                          0
                          То, что благодаря Escape Analysis объекты создаются в стеке — миф. Подробнее, wikis.oracle.com/display/HotSpotInternals/EscapeAnalysis
                            0
                            Если кратко, в стеке создаётся не сам объект, а только его поля по списку.
                      +1
                      Escape analysis уже решает эту проблему.
                      –7
                      Например, при парсинге JSON'a: удобнее сделать структуру. Сейчас приходится создавать «структуру», в которой много вложенных классов с геттерами/сеттерами.
                      • UFO just landed and posted this here
                          –6
                          Публичные поля — это не очень классно.
                          Если брать задачу парсинга JSON'a: то там сеттеры вообще не нужны.

                          • UFO just landed and posted this here
                              +1
                              А чем принципиально отличаются публичные поля в структурах (С#, C++) от публичных полей в объектах?
                          –2
                          Вам заголовки файлов или TCP пакетов читать приходилось? Со структурами это делать куда приятнее, чем вручную парсить byte[].
                          0
                          по-моему они сделали их примерно за год, только в 2009-ом начали проводить в народе фиче-реквест
                            0
                            сам фиче-реквест был создан 16 лет назад. Тогда Sun сказали: «Никому из наших клиентов (кто платит за тех.суппорт) это не надо»
                          +5
                          и еще честные дженерики, а не эту фигню с боксингом
                            –6
                            И protected нормальный! чтобы всем детям видно было, а не только тем что рядом лежат
                            • UFO just landed and posted this here
                                0
                                Про честные дженерики(если я правильно понял автора и не забыл джаву), имеется в виду, что в джаве нельзя написать:
                                ArrayList<int> 
                                

                                Можно только:
                                ArrayList<Integer> 
                                

                                Что может привести к лишнему боксингу/анбоксингу:
                                ArrayList<Integer> list = new ArrayList<Integer>();
                                list.add(42); // Тут произойдет автоматический боксинг
                                int number = list.get(0); // а тут анбоксинг
                                


                                В С# можно написать:
                                List<int> list = new List<int>();
                                list.Add(42); // никакого боксинга
                                int number = list[0]; // никакого анбоксинга
                                
                                  +3
                                  Вы понимаете, что такие генеральные переделки сломают совместимость со старыми JVM?
                                    +1
                                    Вообще не совсем понятно зачем держаться за нее? В мире .Net никого не удивляет, что новая программа может попросить новую версию фреймворка.
                                      +6
                                      И именно по этому многие выбирают java для серверов :)
                                        0
                                        В смысле — новая программа требует новый фреймворк, новый фреймворк требует новую ОС, ОС требует новое железо?
                                        Ну да, такой шанс есть. Но на данный момент мне почему-то кажется, что Oracle уже могли бы пожертвовать обратной совместимостью и избавиться от кучи костылей. Тем более, что насколько мне известно, совместимость все равно оставляет желать лучшего и не является стопроцентной. Поправьте меня, если я ошибаюсь.
                                          +3
                                          Совместимость в джаве очень сильная. Это одна из главных стратегических линий платформы.

                                          Преимуществ уйма.
                                          Вы можете без опасений пользоватся старыми либами и они будут работать так как надо.
                                          Например ваш проект использует либу А, которая давно не поддерживается и не совместима с новым фреймворком и вы захотели добавить либу Б, которой нужна новая версия фреймворка.Что выбрать?
                                          И еще. Серьезное банковское серверное приложение. Вы обновили фреймворк, потеряв совместимость. Вы должны молить бога чтоб баги всплыли в тестах, а не на продакшене.

                                          Разве в С# нет обратной совместимости?
                                            0
                                            Я видимо неточно написал. Конечно старое приложение и старая либа под новым фреймворком заработает. Обратное неверно — новое приложение под старым фреймворком не заработает.
                                      0
                                      Я не предлагаю так сделать в Java. Я попытался пояснить, что, вероятно, имелось в виду под «честными дженериками» в данном случае.
                                      Но тем не менее? я хочу заметить, что и в Java и C# дженерики появились уже после релиза языка. Так что проблемы совметимости были не только у авторов Java.
                                        +1
                                        в итоге MS сделали довольно криво решение — System.Collections.Generic namespace
                                        +1
                                        пример в студию!
                                        –6
                                        Дело не только в том, как писать. В Java все эти дженерики при компиляции преобразуются в инстанциированные классы (что-то вроде ArrayListOfInteger). В рантайме инстанциировать новый дженерик нельзя, только путем компиляции в рантайме. И в reflection не очень удобно анализировать дженерики.

                                        В .NET дженерики «честные» (после компиляции так и остаются дженериками), можно инстанциировать в рантайме и reflection гораздо приятнее.
                                          +1
                                          Если бы в рантайме оно преобразовывалось в ArrayListOfIntegers — это не было бы проблемой как раз, мы бы по прежнему могли понять, что происходит. Проблема как раз в том, что оно преобразуется просто в ArrayList. Все, что в угловых скобках, по сути удаляется после компиляции
                                            –1
                                            Да, точно, спасибо за уточнение. Давно изучал этот вопрос, подзабыл детали.
                                            Еще, насколько я помню, такая особенность позволяет в рантайме подсовывать элементы «не того типа» в ArrayList, т.к. у него тип элементов Object. Но это только при намеренном желании сломать, конечно.
                                            +3
                                            В Java генерики работают через erasure, а не так как вы говорите.
                                          • UFO just landed and posted this here
                                              –3
                                              Вообще-то, в C# так можно не из-за «нормальных дженериков», а из-за того, что int — это класс, а не примитив
                                                0
                                                Вообще int это структура.
                                          • UFO just landed and posted this here
                                              0
                                              Что?
                                              protected виден всем детям (и детям детей тоже)
                                              • UFO just landed and posted this here
                                              +1
                                              Вы перепутали protected с доступом по умолчанию?
                                              +3
                                              Ну да, а ещё Dynamic Runtime, аналог Async/Await, Extension methods, ну и дальше по списку en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java

                                              Такими темпами, работы у ребят из Oracle где-то до 2020-ого.
                                                –2
                                                Такими темпами Java безнадежно отстанет и загнется (платформа JVM никуда не денется, но язык вполне может смениться).
                                                Пока в Java будут реализовывать поддержку фич десятилетней давности, другие языки будут обогащаться новыми фичами.
                                                  +1
                                                  Покуда они будут компилиться в код, выполняемый JVM и без гемороя переезжать с платформы на платформу — нет проблем.
                                                  0
                                                  Async/await? Уже есть: commons.apache.org/sandbox/commons-javaflow/
                                                  Я к этому делу прикрутил ещё и kryo и пишу бинарный образ continuation'а в blob в БД. Можно хоть перезагрузить сервак, пока поток ждёт. Я это использую для того, чтобы программировать workflow на java без всяческих event'ов и listener'ов. Получается прямо как BPEL, только Java вместо XML. А continuation'ы использую, чтобы ожидать ответ от пользователей. Пока пользователь не выполнит назначенную ему задачу, continuation будет мирно лежать себе в БД. Единственный минус javaflow — плохо поддерживается reflection и встроенный механизм proxy. Последний мне был нужен, поэтому я взял в руки ASM и запилил свой Proxy с поддержкой javaflow.

                                                  Dynamic Runtime? Я правильно понимаю, что это просто библиотека над стандартным CLR + ключевое слово dynamic? Последнее не знаю, зачем нужно, а библиотеки в Java, думаю, и так подобные имеются. Плюс появившаяся в Java 7 инструкция INVOKEDYNAMIC.

                                                  Extension methods не нужны (и порой даже вредны), без LinQ, конечно, тяжело, но есть Querydsl. С появлением лямбд всё будет ещё веселее. Наверняка кто-нибудь сделает querydsl на стероидах. Теоретически, если сюда подключить манипуляцию с байт-кодом, то можно получить вариант, практически не отличимый от LinQ. А вот то, что не сделали нормальный вывод типов — это жаль, конечно.

                                                  Зато в .NET нет java.util.concurrent (или уже появился?), нет перекомпиляции методов JIT'ом в более быстрые аналоги на основе статистики выполнения (или тоже уже сделали?) и дальше по списку.
                                              +14
                                              Лямбды всё равно будут кастрированными и с граблями.
                                                –3
                                                Почему то все забывают, что ламбды то нам обещают в 8-ка, а вот полноценных замыканий нет. Сейчас изнутри лямбды (как и безымянного вложенного класса) можно обращаться только к финальным локальным переменным метода в котором они создаются. Как это не поразительно в 8-ке на собираются менять этот ужас. Даже в JavaScript замыкания реализованы, а в Java нет.
                                                  +4
                                                  Во-первых, там вводится понятие «эффективно финальных переменных», т.е. которые хоть и не помечены final, но присваиваются только один раз, их можно сразу использовать в лямбдах. Во-вторых, возможность модификации любой переменной — это опасно в связи с многопоточностью, об это сразу будут обжигаться много народу. В-третьих, полноценные замыкания это опять генеральная переделка JVM, т.к. придётся вводить какую-то сущность типа «указатель на фрейм стека» или что-то подобное.
                                                    0
                                                    Замыкания и лямбды можно реализовать на уровне синтаксиса без добавления новых инструкций в байткод и изменения виртуальной машины. Доказательство: C#, Scala.
                                                      0
                                                      Можно, только это будет либо
                                                      1) неэффективно с точки зрения JVM (плохая HotSpot-компиляция, много временных объектов, туча мелких анонимных классов)
                                                      2) это будет другой язык, не только с другим синтаксисом, но и с другой семантикой
                                                      Ну вот и пользуйтесь тогда Scala. (только не говорите, что там проблем нет)
                                                    +2
                                                    Полноценные замыкания элементарно имитируются через ObjectHolder
                                                  +2
                                                  Кто бы сомневался. А ведь первоначально вообще планировалось выпустить Лямбду в составе Java 7 ещё несколько лет назад.
                                                    +7
                                                    Всё, точно пора мигрировать на Groovy или Scala. Они намного динамичнее развиваются.
                                                      –1
                                                      Жаль только, что у скалы компилятор тормозной, хреновая поддержка IDE, проблемы с производительностью и ещё куча мелких проблем. А груви так вообще какая-то полудинамика.
                                                      +4
                                                      Марк задаёт вопрос: а какие вообще были варианты у ребят из Oracle?

                                                      Варианты больше напоминают отмазки. Почему-то новые версии .NET вместе C# выходят регулярно, синтаксических плюшек там гораздо больше.
                                                      Видимо просто у Oracle другие приоритеты. Или большому Oracle просто не до Java.
                                                        0
                                                        Я думаю стоит учесть тот факт что .NET идет под Windows платформу только, MONO не рассматриваем. Исходя из этого времени на тестирование .NET релиза нужно заметно меньше, в отличие от Java с таким набором поддерживаемых платформ.
                                                          +2
                                                          Почему не рассматриваем? Рассмотрите. Он уже давно стабильный и полностью поддерживает спецификацию.
                                                          • UFO just landed and posted this here
                                                              0
                                                              А вот, кстати, любопытно, где больше разработчиков — в подразделении Microsoft по C# + разработчики mono или в Oracle в подразделении по Java? Не думаю, что разница в разработчиках такая же огромная, как в функциональности.
                                                            +1
                                                            Да, не спорю. И Java более старая платформа, поэтому многие новые фичи делаются через костыли ради обратной совместимости.
                                                            Но это все больше касается JVM. А синтаксис можно делать сколь угодно разнообразным и красивым, если его можно скомпилировать все в тот же байткод. В этой части затраты одинаковы.

                                                            Лямбда-выражения появились в C# 3.0, 6 лет назад. В Java они будут добавлены только в следующем году. Реально 7 лет требовалось, чтобы реализовать лямбда-выражения? Думаю причина тут все-таки не в трудоемкости, а в приоритетах.
                                                              +3
                                                              Lambdas это не просто синтаксис, они компилируются в байт-код с использованием таких фич как method handles и invokedynamic, которые появились только в Java 7.
                                                                0
                                                                Я в целом про то, что синтаксис Java не улучшается годами. То, что в других языках есть из коробки, здесь реализуется через паттерны.
                                                                  0
                                                                  Я в целом про то, что синтаксис Java не улучшается годами.

                                                                  А нужно оно? Золотое правило: работает — не трожь.

                                                                  То, что в других языках есть из коробки, здесь реализуется через паттерны.

                                                                  То что можно сделать библиотеками — не нужно делать на уровне языка. Однородность и простота синтаксиса это плюс а не минус.
                                                                  0
                                                                  То, как их сделать — вопрос реализации. Можно было реализовать по-другому, раньше и с замыканиями.
                                                                    +1
                                                                    Можно было, для каждой лямбды генерировать анонимный класс (тем самым дополнительно напрягая GC).
                                                                    –1
                                                                    ничего подобного, лямбды это синтаксический сахар над интерфейсами с одним методом.
                                                                      +4
                                                                      Нет. Прочитайте Translation of Lambda Expressions. Компиляция лямбды создаёт в базовом классе скрытый метод наподобие static void lambda$1(...) { }, а при выполнении при помощи некторой «магии» берётся ссылка на этот метод и превращается в экземпляр интерфейса (нечто вроде dynamic proxy).
                                                              –6
                                                              Вообще, я считаю что зря они уходят в функциональное программирование с этими лямбдами (поправьте, если не так).
                                                              На данный момент я нашел только одно применение лямбдам: эмуляция C# делегатов.
                                                                +3
                                                                Код читаться будет проще во многих случаях. Вместо:

                                                                void DoSomething()
                                                                {
                                                                    Console.Write("Hello ");
                                                                
                                                                    Task.Factory.StartNew(PrintWorldWithDelay);
                                                                
                                                                    // тут много кода
                                                                
                                                                    Console.ReadLine();
                                                                }
                                                                
                                                                // и тут много
                                                                
                                                                void PrintWorldWithDelay()
                                                                {
                                                                    Thread.Sleep(2000);
                                                                    Console.Write("World! (after 2 sec)");
                                                                }
                                                                

                                                                так:

                                                                void DoSomething()
                                                                {
                                                                    Console.Write("Hello ");
                                                                
                                                                    Task.Factory.StartNew(() =>
                                                                    {
                                                                        Thread.Sleep(2000);
                                                                        Console.Write("World! (after 2 sec)");
                                                                    });
                                                                
                                                                    // много кода
                                                                
                                                                    Console.ReadLine();
                                                                }
                                                                


                                                                Хотя, кому-то такой стиль может показать «неправильным», но я без него жить не могу. Намного быстрее понять, что происходит и в какой последовательности.
                                                                  +4
                                                                  new Thread(new Runnable() { public void run() {
                                                                          Thread.sleep(2000);
                                                                          System.out.println("World! (after 2 sec)");
                                                                      }}).start();


                                                                  не катит?
                                                                  Или даже так:
                                                                  new Thread(
                                                                        public void run() {
                                                                          Thread.sleep(2000);
                                                                          System.out.println("World! (after 2 sec)");
                                                                      }).start();
                                                                    +1
                                                                    Катит, конечно, но многие ругают Java именно за многословность.
                                                                      +1
                                                                      В случае с лямбдами public void run() превратится в () =>
                                                                      экономия не очень существенная. И совсем другое дело, если бы принципиально это было невозможно и пришлось бы всегда писать отдельные методы.
                                                                      Хотя наверняка найдутся и более удачные примеры. А вот лично мне как раз больше мешает боксинг дженериков, как писали выше.
                                                                        0
                                                                        Если точнее, то
                                                                        new Runnable() { public void run() {
                                                                        плюс ещё одна закрывающая скобка. И по многим правилам оформления обычно это разбивают на минимум 2 строки.
                                                                          0
                                                                          посчитайте, вроде обычных и фигурных скобок правильное количество.
                                                                          на строки я не разбивал, чтобы было похоже на указанный выше C# пример, но это все не принципиально, мы ж говорим об общем принципе.
                                                                          +1
                                                                          Проблема в том, что будет создан анонимный класс. Это довольно дорого (если это делать очень часто). Лямбды — это не только новый синтаксис, это очень полезная вещь. Можно было бы, конечно, просто оптимизировать создание анонимного класса из интерфейса, в котором определен только один метод, но это было бы непрозрачно — в вашем примере вариант с Runnable был бы оптимизирован, а вариант с Thread — нет
                                                                    0
                                                                    Из очевидного — работа с коллекциями. А вообще это еще одна степень свободы, которую можно использовать при проектировании.
                                                                      0
                                                                      Лямбды позволяют реализовывать красивую работу с коллекциями (см. LINQ) а в последствии и с событиями (см. Rx).
                                                                        0
                                                                        Вот этого не знал. Спасибо за уточнение.
                                                                      +9
                                                                      Для баланса комментариев напишу, что лично мне лямбд больше всего в современной Яве не хватает. И, скажу более, пожалуй единственное, что ей не действительно не хватает и что реально важно.
                                                                        0
                                                                        Сейчас вполне реально и возможно даже нужно писать multi-language проекты. Например Java/Scala. Все равно все собирается в байт-код. В Scala вам и лямбды будут)
                                                                          –5
                                                                          А ничего что из лямбды нельзя поменять локальную переменную?
                                                                            0
                                                                            Через трюк — можно.
                                                                            int[] result = new int[1];
                                                                            callSomething(() => { ...; result[0] = x });
                                                                            
                                                                            А без трюков — будет много сложностей, как у людей, так и у компилятора и JVM, поверьте.
                                                                              +2
                                                                              Это не трюк, а костыль. Когда я в первый раз увидел подобный код (там использовался AtomicInteger), я включил повышенный внутренний уровень опасности, ожидая хитрой работы с потоками, оказалось зря — это был как раз этот «трюк»: использование вещей для этого не предназначенных, чтобы обойти искуственное ограничение. По-моему, сложность для людей очевидна.
                                                                                +1
                                                                                Вот допустим, метод callSomething запускает лямбду асинхронно в новом треде, и после этого вызывающий метод сразу завершается. Лямбда посчитала результат — какую она локальную переменную сможет теперь изменить, если уже от вызывающего метода и стека не осталось? Ну вы-то сообразите, может быть, что такого делать нельзя, а как это компилятору объяснить — сможете?
                                                                                  0
                                                                                  Вы не тот вопрос задаете.

                                                                                  Если java-программист хочет использовать замыкание (изменение локальной переменной из лямбды), то java сообщество не бьёт его палкой, а рекомендует использовать костыль в виде int[] или AtomicInteger. Возникает вопрос, почему это окостылевание не делает компилятор, если оно и так общепринято? Ответ я не знаю.
                                                                                    0
                                                                                    Если java-программист так хочет сделать — почти наверняка он пишет не очень хороший код. И поэтому то его и надо бить палкой.
                                                                                0
                                                                                Это, кстати, Thread Unsafe код и, соответственно, гонка, даже если callSomething корректно передаст вашу Лямбду в другой поток.
                                                                                  0
                                                                                  Как заранее понять, что он thread unsafe (не заглядывая внутрь)? (и как дать это понять компилятору?)
                                                                                    0
                                                                                    Компилятору абсолютно пофигу сейф ваш код или нет. Дать ему понять, с-но никак.
                                                                                    Заранее понять очень просто, если можно доказать, что всегда будет ребро happens-before, значить трейд сейф, иначе не трейд сейф. Тут на момент вызова лямбды не будет таких ребер. Можно переписать например так:
                                                                                    ArrayBlockingQueue result = new ArrayBlockingQueue(1);
                                                                                    callsomething(() => {… result.put(x);});
                                                                                +3
                                                                                Я, если честно, вообще полагаю, что зря в Яве локальные переменные не являются final по умолчанию. Так что ничего страшного, их вообще крайне редко приходится менять.
                                                                                  0
                                                                                  В Intellij IDEA можно поставить декларирование локальных переменных всегда финальными. Советую.
                                                                                    0
                                                                                    Единственное когда это мешает, когда переменная кидает не RuntimeException, при какой то инициализации. Скажем мы хотим вытащить значение какого то обьекта из чего то, а эта операция вызывает эксепшн, с которым ничего вовсе не хочется делать. И выходит что то типо
                                                                                    ...
                                                                                    Foo foo = null;
                                                                                    try{
                                                                                        foo = getFromSomewhere();
                                                                                    } catch (IDontCareException e) {
                                                                                        log.info(e, "looks like foo is not there);
                                                                                    }
                                                                                    
                                                                                    if (foo != null) {
                                                                                        doSomethingWithFoo(foo);
                                                                                    }
                                                                                    
                                                                                    doSomethingElse();
                                                                                    ...
                                                                                    
                                                                                      0
                                                                                      А почему не так?
                                                                                      ...
                                                                                      try{
                                                                                          final Foo foo = getFromSomewhere();
                                                                                          doSomethingWithFoo(foo);
                                                                                      } catch (IDontCareException e) {
                                                                                          log.info(e, "looks like foo is not there);
                                                                                      }
                                                                                      
                                                                                      doSomethingElse();
                                                                                      ...
                                                                                      

                                                                                  +1
                                                                                  И правильно. В иммутабельном стиле программирования потенциально меньше ошибок
                                                                                    +6
                                                                                    ничего. ибо не нужно. ибо за такой код надо по рукам бить

                                                                                Only users with full accounts can post comments. Log in, please.