Статьи

Ява, если бы это был лучший мир

Просто немного мечтать о лучшем мире, где некоторые старые ошибки в платформе Java были бы исправлены, а некоторые потрясающие недостающие функции были бы реализованы. Не пойми меня неправильно. Я думаю, что Java потрясающая. Но у него все еще есть некоторые проблемы, как и у любой другой платформы. Без какого-либо определенного порядка, без претензий на что-то почти исчерпывающее и, самое главное, без претензий на то, что они хорошо продуманы и полностью правильны, я желаю следующих вещей:

Serialisability

Внутри объекта сериализуемость является значением по умолчанию. Если вы не хотите, чтобы элемент был сериализуемым, отметьте его как «временный». С какой стати мы должны добавить этот глупый маркер?

интерфейс «Сериализуемый» для всех наших классов?

Все объекты должны быть сериализуемыми по умолчанию. Несериализуемость должна быть «функцией», которая отмечена явно

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

клонирование

Поскольку все объекты должны быть сериализуемыми по умолчанию,

Все объекты также должны быть клонируемыми по умолчанию. Неклонируемость должна быть «особенностью», которая отмечена явно

Кроме того, мелкое клонирование вряд ли когда-либо будет полезным. следовательно

Все объекты должны клонировать себя по умолчанию. Мелкое клонирование может быть реализовано явно

Обратите внимание, что метод clone должен быть каким-то собственным методом в java.lang.System или какой-либо другой утилите. Он не должен быть на java.lang.Object, что позволяет клиентскому коду реализовать правильную интерпретацию клонирования без каких-либо случайных конфликтов имен. Альтернативно, аналогичные частные методы обратного вызова могут быть реализованы так же, как это делается для сериализации, если клонирование должно быть настроено.

Числа без знака

Почему это не часть Java?

Должна быть беззнаковая версия всех целочисленных примитивов, а также оболочек java.lang.Number.

Примитивы

Примитивы — боль в поддержке в API. int и Integer должны быть одинаковыми с точки зрения синтаксиса. int [] и Integer [] тоже должны быть

Примитивы и их оболочки должны быть лучше интегрированы в язык и в JVM

Это, вероятно, невозможно решить, не отказываясь от преимущества в производительности, которое дают истинные примитивы. Смотрите Скала …

свойства

Геттеры и сеттеры на самом деле не самые современные.

Свойства должны поддерживаться более формально

Смотрите также недавнюю статью и комментарии к этому блогу: http://blog.jooq.org/2013/01/12/bloated-javabeans-part-ii-or-dont-add-getters-to-your-api/

Коллекции

API коллекции должен быть лучше интегрирован с языком. Как и во многих других языках, должно быть возможно разыменовать содержимое коллекции, используя квадратные скобки и фигурные скобки. Синтаксис JSON будет очевидным выбором. Должно быть возможно написать:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
// Translates to new ArrayList<>(...);
List<Integer> list = [ 1, 2, 3 ];
 
// Translates to list.get(0);
Integer value = list[0];
 
// Translates to list.set(0, 3);
list[0] = 3;
 
// Translates to list.add(4);
list[] = 4;
 
// Translates to new LinkedHashMap<>(...);
Map<String, Integer> map = { 'A': 1, 'B': 2 };
 
// Translates to map.get(0);
Integer value = map['A']
 
// Translates to map.put('C', 3);
map['C'] = 3;

ThreadLocal

ThreadLocal может быть хорошей вещью в некоторых контекстах. Вероятно, концепция ThreadLocal не на 100% звучит, так как может вызвать утечку памяти . Но при условии, что проблем не было,

threadlocal должен быть ключевым словом, как volatile и transient

Если transient заслуживает того, чтобы быть ключевым словом, тогда threadlocal также должен быть. Это будет работать следующим образом:

1
2
3
4
5
6
7
8
9
class Foo {
  threadlocal Integer bar;
 
  void baz() {
    bar = 1;           // Corresponds to ThreadLocal.set()
    Integer baz = bar; // Corresponds to ThreadLocal.get()
    bar = null;        // Corresponds to ThreadLocal.remove()
  }
}

Конечно, такое ключевое слово может быть применено и к примитивам

использованная литература

Ссылки — это что-то странное в Java. Они реализованы как объекты Java в пакете java.lang.ref, но обрабатываются JVM и GC очень специально.

Как и для threadlocal, здесь должны быть ключевые слова для обозначения ссылки.

Конечно, с введением дженериков добавление такого ключевого слова дает лишь небольшой выигрыш. Но все еще кажется вонючим, что некоторые классы «очень особенные» в JVM, а не функции синтаксиса языка.

отражение

Пожалуйста! С какой стати это так многословно? Почему Java (Java-the-language) не может быть намного более динамичной? Я не спрашиваю о Smalltalk- динамике, но нельзя ли как-то встроить в язык рефлексию, как синтаксический сахар?

Язык Java должен предусматривать специальный синтаксис для отражения

Конечно, можно добиться некоторого облегчения боли на уровне библиотеки. JOOR является одним из примеров. Есть много других.

Интерфейсы

Интерфейсы в Java всегда кажутся очень странными. В частности, с помощью методов расширения Java 8 они начинают терять свое право на существование, поскольку они приближаются к абстрактным классам. Конечно, даже в Java 8 основное отличие состоит в том, что классы не допускают множественное наследование. Интерфейсы делают — по крайней мере, они допускают множественное наследование спецификации (абстрактные методы) и поведения (методы по умолчанию), а не для состояния.

Но они все еще чувствуют себя странно, главным образом потому, что их синтаксис отличается от классов, а их функции сходятся. Почему группа экспертов по лямбде решила ввести ключевое слово по умолчанию? Если интерфейсы допускают абстрактные методы (как сегодня) и конкретные методы (методы защитника, методы расширения), почему интерфейсы не могут иметь тот же синтаксис, что и классы? Я спросил группу экспертов без удачи: http://mail.openjdk.java.net/pipermail/lambda-dev/2012-August/005393.html . Тем не менее, я хотел бы этого …

Синтаксис интерфейса должен быть точно таким же, как синтаксис класса, где это уместно

Это включает в себя статические методы, финальные методы, приватные методы, приватные методы пакета, защищенные методы и т. Д.

Видимость по умолчанию

Видимость по умолчанию не должна определяться отсутствием частного / защищенного / публичного ключевого слова. Во-первых, в классах и интерфейсах это отсутствие обрабатывается по-разному. Тогда это не очень читабельно.

Видимость по умолчанию должна быть указана с помощью ключевого слова package или local

литералы

Это было бы отличным дополнением в повседневной работе.

Должны быть список, карта, регулярное выражение, кортеж, запись, строка (улучшено), литералы диапазона

Я уже писал об этом в блоге: http://blog.jooq.org/2012/06/01/array-list-set-map-tuple-record-literals-in-java/ . Некоторые идеи, упомянутые Брайаном Гетцем в списке рассылки lambda-dev, были найдены здесь: http://mail.openjdk.java.net/pipermail/lambda-dev/2012-May/004979.html

1
2
3
4
5
6
#[ 1, 2, 3 ]                          // Array, list, set
#{ 'foo' : 'bar', 'blah' : 'wooga' // Map literals
#/(\d+)$/                             // Regex
#(a, b)                               // Tuple
#(a: 3, b: 4)                         // Record
#'There are {foo.size()} foos'        // String literal

Я добавлю

1
#(1..10)                              // Range (producing a List)

окончательный

Методы, атрибуты, параметры, локальные переменные, все они могут быть объявлены как «окончательные». Неизменность — это хорошая вещь во многих отношениях, и ее следует поощрять (я скоро напишу об этом в блоге). Другие языки, такие как Scala, различают ключевые слова «val» и «var». В дополнение к впечатляющим возможностям вывода типов этих языков, в большинстве случаев val предпочтительнее, чем var. Если кто-то хочет выразить изменяемую переменную, он все равно может использовать «var»

Final должен быть поведением по умолчанию для членов, параметров и локальных переменных

Override

Случайно переопределять метод опасно. Другие языки решили эту проблему, вызвав ошибки компиляции в переопределениях

Ключевое слово override должно быть введено, чтобы явно переопределить метод

Некоторые компиляторы Java (например, компилятор Eclipse) могут быть настроены на выдачу предупреждения / ошибки об отсутствии аннотации java.lang.Override. Однако это действительно должно быть ключевое слово, а не аннотация.

Модули

Управление зависимостями — это кошмар в Java. Есть еще один язык, который строит модули компиляции в терминах модулей: Fantom . Стивен Колебурн (парень из JodaTime) — большой поклонник Fantom, он выступил с речью в Devoxx. Время от времени он также ведет блог о Fantom: http://blog.joda.org/search/label/fantom

Единица компиляции должна быть выражена в виде «модуля» / файла jar

Это, конечно, сделает Maven устаревшим, так как компилятор Java уже может обрабатывать зависимости гораздо лучше.

Варарги и дженерики

Давай. @SafeVarargs ?? Конечно, это никогда не может быть решено полностью правильно из-за стирания универсального типа. Но до сих пор

Не должно быть стирания универсального типа

Кортежи и записи

Я действительно думаю, что это чего-то не хватает в Java

Должна быть языковая поддержка для кортежей и записей.

Scala имеет встроенные кортежи до степени 22, .NET поддерживает кортежи до степени 8. Это было бы неплохо и в языке Java. В частности, было бы неплохо иметь записи (или структуры). Как упоминалось ранее, для кортежей и записей также должны быть литералы. Что-то в этом роде:

1
2
#(a, b)                               // Tuple
#(a: 3, b: 4)                         // Record

составитель

API-интерфейс компилятора, выходящий далеко за пределы добавления обработки аннотаций, был бы неплохим. Я хотел бы иметь возможность расширять сам язык Java. Я хотел бы встраивать операторы SQL непосредственно в код Java, подобно тому, как SQL можно встраивать в PL / SQL. Конечно, такой код SQL будет поддерживаться библиотекой, такой как jOOQ .

API компилятора должен допускать произвольное расширение языка

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

Тип вывода

Если однозначно, не может ли вывод типа быть столь же мощным, как у Скалы ? Я не хочу записывать полный тип каждой локальной переменной. Скала локальный тип вывода должен поддерживаться

Перегрузка оператора

ОК, это очень религиозная тема. Многие из вас не согласятся. Но мне просто нравится

Java должна поддерживать перегрузку операторов

Некоторые библиотечные операции просто лучше выражаются с помощью операторов, а не методов. Подумайте об ужасно многословном API BigInteger и BigDecimal.

Есть еще идеи? Добавьте комментарии!

Конечно, лямбды и методы расширения отсутствуют, а дженерики стерты. Хотя последнее никогда не будет исправлено, первое будет в Java 8. Поэтому давайте простим Sun и Oracle за то, что заставили нас так долго ждать лямбды

Ссылка: Java, если бы это был лучший мир от нашего партнера по JCG Лукаса Эдера из блога JAVA, SQL и JOOQ .