Я наткнулся на это предложение Брайана Гетца о классах данных в Java и сразу понял, что у меня тоже есть несколько идей о том, как сделать Java лучше как язык. У меня их действительно много, но это краткий список пяти самых важных.
Глобальные переменные . В Java есть синглтоны , которые, как мы все знаем, не что иное, как глобальные переменные . Не было бы замечательно включить глобальные переменные в Java и избавиться от синглетонов. PHP, JavaScript, Ruby и многие другие языки имеют их, почему нет Java? Посмотрите на этот код:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
class User { private static final User INSTANCE; private User() {} public static User getInstance() { synchronized (User.INSTANCE) { if (User.INSTANCE == null) { User.INSTANCE = new User(); } } return User.INSTANCE; } public String getName() { // return user's name }} |
Затем для доступа к нему мы должны использовать:
|
1
|
String name = User.getInstance().getName(); |
Это синглтон. Видите, как это многословно? Мы можем просто заменить его глобальной переменной ( global — это ключевое слово, которое я предлагаю использовать):
|
1
|
global User user; |
А потом:
|
1
|
user.getName(); |
Гораздо меньше кода для написания и намного проще для чтения!
Глобальные функции и пространства имен
Чтобы сгруппировать статические методы вместе, мы создаем служебные классы , где мы должны определить частные конструкторы, чтобы предотвратить их создание. Кроме того, мы должны помнить, в каком конкретном служебном классе находится статический метод. Это просто дополнительные хлопоты. Я предлагаю добавить глобальные функции в Java и необязательные «пространства имен» для их группировки. Взгляните на этот служебный класс:
|
1
2
3
4
5
6
7
8
9
|
class TextUtils { private TextUtils() {} public static String trim(String text) { if (text == null) { return ""; } return text.trim(); }} |
Теперь посмотрим на эту глобальную функцию с пространством имен:
|
1
2
3
4
5
6
7
8
|
namespace TextUtils { String trim(String text) { if (text == null) { return ""; } return text.trim(); }} |
Я хочу сказать, что поскольку мы уже используем классы в качестве наборов функций, давайте сделаем это более удобным. В некоторых приложениях нам даже не понадобятся пространства имен, только глобальные функции, как в C и C ++.
Полный доступ к личным атрибутам и методам
Чтобы получить доступ к приватному атрибуту или методу объекта извне, мы должны использовать Reflection API . Это не особенно сложно, но это занимает несколько строк кода, которые не так легко прочитать и понять:
|
1
2
3
4
5
6
7
8
|
class Point { private int x; private int y;}Point point = new Point();Field field = point.getClass().getDeclaredField("x");field.setAccessible(true);int x = (int) field.get(point); |
Я предлагаю разрешить любому объекту доступ к любым атрибутам и методам другого объекта:
|
1
2
|
Point point = new Point();int x = point.x; |
Конечно, если они закрытые, компилятор выдаст предупреждение. Во время компиляции вы просто игнорируете предупреждение и идете дальше. Если вы действительно заботитесь об инкапсуляции, обратите внимание на предупреждение и сделайте что-нибудь еще. Но в большинстве случаев программисты будут игнорировать это, так как в любом случае они с удовольствием использовали бы API Reflection.
NULL по умолчанию
Было бы удобно вызывать конструкторы и методы с неполным набором аргументов. Аргументы, которые мы не предоставляем, по умолчанию будут иметь значение null . Кроме того, когда метод должен что-то вернуть, но нет оператора return , Java должна вернуть null . Это почти точно так, как это работает в PHP, Ruby и многих других языках. Я считаю, что это будет удобной функцией для Java разработчики тоже.
обезьяны
Нам не нужно определять столько методов, когда некоторые аргументы являются необязательными. Перегрузка метода очень многословна и трудна для понимания. Вместо этого у нас должен быть один метод с длинным списком аргументов. Некоторые из них будут предоставлены вызывающей стороной, другие будут установлены в null . Метод решит, что делать, например:
|
1
2
3
4
5
|
void save(File file, String encoding) { if (encoding == null) { encoding = "UTF-8"; }} |
Затем мы просто вызываем save(f) или save(f, "UTF-16") . Метод поймет, что мы имеем в виду. Мы также можем сделать его еще более удобным, как это делается в Ruby, предоставляя аргументы метода по именам:
|
1
|
save(file: f, encoding: "UTF-16"); |
Кроме того, когда нечего возвращать, метод должен по умолчанию возвращать null . Написание return null является пустой тратой строки кода и не улучшает читаемость. Взглянем:
|
1
2
3
4
5
|
String load(File file) { if (file.exists()) { return read_the_content(); }} |
Из этого кода очевидно, что если файл существует, метод загружается и возвращает его содержимое. Если нет, он возвращает null , что будет хорошим индикатором для вызывающей стороны, что что-то не так, и содержимое файла недоступно.
Добытчики и сеттеры
Я думаю, что очевидно, что нам нужна эта функция: каждый закрытый атрибут должен автоматически иметь установщик и получатель . Не нужно создавать их, Java предоставит их «из коробки», как это делают Kotlin и Ruby . Какой смысл иметь атрибут, если нет геттеров и сеттеров для его чтения и изменения, верно?
С этой новой функцией нам больше не понадобится помощь Lombok или IntelliJ IDEA .
Может быть, я должен превратить свои идеи в официальные предложения для JCP . Что вы думаете?
Вы также можете найти эти посты интересными: каждый частный статический метод является кандидатом в новый класс ; Пытаться. В заключение. Если. Не. Ноль. ; Почему NULL это плохо? ; Почему многие заявления о возвращении являются плохой идеей в ООП ; Могут ли объекты быть друзьями? ;
| Опубликовано на Java Code Geeks с разрешения Егора Бугаенко, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Пять функций, которые делают Java еще лучше
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |
