Я наткнулся на это предложение Брайана Гетца о классах данных в 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, являются их собственными. |