Статьи

Пять возможностей сделать Java еще лучше

Я наткнулся на это предложение Брайана Гетца о классах данных в Java и сразу понял, что у меня тоже есть несколько идей о том, как сделать Java лучше как язык. У меня их действительно много, но это краткий список пяти самых важных.

Идиократия (2006) Майк Джадж

Глобальные переменные . В 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, являются их собственными.