20 приемов работы на Java, которые помогут вам улучшить качество кода
Источник:
Medium
Вашему вниманию предлагается набор рекомендаций, соблюдение которых поможет улучшить качество вашего Java-кода.
1. По возможности отдавайте предпочтение примитивам, а не классам-оболочкам
Long idNumber;
long idNumber;
2. Попробуйте использовать подходящий тип для вашей переменной
Если два или более типов удовлетворяют вашим функциональным потребностям, используйте тот тип, который занимает меньше места в памяти.
int birthYear;
short birthYear;
int personRunningSpeedKmHour;
byte personRunningSpeedKmHour;
3. При проверке нечетности числа побитовый оператор AND намного быстрее, чем арифметический оператор по модулю
public boolean isOdd(int num) {
return (num & 1) != 0;
}
4. Избегайте избыточной инициализации (0, false, null..)
Не инициализируйте переменные с их инициализацией по умолчанию, например, boolean по умолчанию имеет значение
false, поэтому избыточно инициализировать его значением
false.
String name = null;
int speed = 0;
boolean isOpen = false;
String name;
int speed;
boolean isOpen;
5. Объявляйте членов класса закрытыми везде, где это возможно, и всегда давайте модификатору доступа максимально ограниченный доступ
public int age;
int age;
private int age;
6. Избегайте использования ключевого слова “new” при создании строки
String s1 = new String("AnyString") ;
String s2 = "AnyString" ;
7. Для объединения нескольких строк используйте StringBuilder или StringBuffer вместо использования оператора +
Оператор
+ неэффективен, поскольку компилятор Java создает несколько промежуточных объектов
String перед созданием окончательной объединенной строки.
StringBuilder или
StringBuffer изменяют
String без создания промежуточных объектов
String.
String address = streetNumber +" "+ streetName +" "
+cityName+" "+cityNumber+" "+ countryName;
StringBuilder address = new StringBuilder(streetNumber).append(" ")
.append(streetName).append(" ").append(cityName).append(" ")
.append(cityNumber).append(" ").append(countryName);
Учтите, что
StringBuilder не потокобезопасен, не синхронизирован, но он быстрее, чем
StringBuffer, который потокобезопасен и синхронизирован.
8. Используйте подчеркивание в числовых литералах
int myMoneyInBank = 58356823;
int myMoneyInBank = 58_356_823;
long billsToPay = 1000000000L;
long billsToPay = 1_000_000_000L;
9. Избегайте использования “for loop” с индексами
Не используйте
for loop с переменной индекса (или счетчика), если вы можете заменить его расширенным циклом
for (начиная с Java 5) или
forEach (начиная с Java 8). Это связано с тем, что переменная индекса подвержена ошибкам, поскольку мы можем случайно изменить ее в теле цикла или начать индекс с
1 вместо
0.
for (int i = 0; i < names.length; i++)
{ saveInDb(names[i]); }
for (String name : names)
{ saveInDb(name); }
10. Заменяйте try-catch-finally на try-with-resources
Scanner scanner = null;
try
{scanner = new Scanner(new File("test.txt"));
while (scanner.hasNext())
{System.out.println(scanner.nextLine());}}
catch (FileNotFoundException e)
{e.printStackTrace();}
finally
{if (scanner != null)
{scanner.close();}}
try (Scanner scanner = new Scanner(new File("test.txt")))
{while (scanner.hasNext())
{System.out.println(scanner.nextLine());}}
catch (FileNotFoundException fnfe)
{fnfe.printStackTrace();}
11. Не используйте пустые блоки catch
Пустой блок
catch приведет к тому, что программа молча выйдет из строя и не даст никакой информации о том, что пошло не так.
try
{ productPrice = Integer.parseInt(integer); }
catch (NumberFormatException ex)
{ }
try
{ productPrice = Integer.parseInt(integer); }
catch (NumberFormatException ex)
{unreadablePrices.add(productPrice);
log.error("Cannot read price : ", productPrice );
}
12. Избегайте Null Pointer Exception, где это возможно.
Старайтесь избегать исключений
Null Pointer Exception, которые могут возникнуть в следующих ситуациях:
- Возврат пустых коллекций вместо возврата элементов Null.
- Частое использование Optional.
- Методы requireNonNull в java.utils.Objects.
- Аннотации NotNull, NotEmpty, NotBlank.
- Objects::nonNull в Streams.
- Методы requireNonNull в java.util.Objects.
13. Добавляйте только необходимые геттеры, сеттеры, конструкторы и избегайте Lombok
Добавляйте только тот код, который вам нужен. Lombok — отличный инструмент, который может помочь вам в создании шаблонного кода, но у него есть некоторые недостатки, такие как несовместимость с IDE, использование непубличного API, и он тесно связан с java-компилятором. Кроме того, начиная с Java 14,
records могут заменить некоторые его утилиты.
14. Чтобы проверить равенство, используйте == для ссылок и equals для объектов
Person p1 = new Person("John","Doe");
Person p2 = new Person("John","Doe");
System.out.println(p1 == p2);
System.out.println(p1.equals(p2));
Более подробную информацию по этой теме вы можете найти на
StackOverflow.
15. Всегда применяйте hashCode при реализации equals
Никогда не забывайте переопределять
hashCode, если вы переопределяете
equals, чтобы не “нарушить контракт”.
Согласно API, результат, возвращаемый методом
hashCode() для двух объектов, должен быть одинаковым, если их методы equals показывают, что они эквивалентны.
16. Отдавайте предпочтение records (начиная с Java 14) для неизменяемых данных
public final class Person {
private final String name;
private final long idNumber;
public Person(String name, long idNumber) {
this.name = name;
this.idNumber = idNumber;
}
public boolean equals(Object other) {
if (other == this) return true;
if (other == null) return false;
if (other.getClass() != this.getClass()) return false;
Person that = (Person) other;
return (this.name.equals(that.name)) && (this.idNumber == that.idNumber);
}
public String toString() {
return name + " " + idNumber;
}
public int hashCode() {
return Objects.hash(idNumber, name);
}
}
record Person(String name, long idNumber) { }
17. Для констант используйте enum или класс final вместо интерфейса
Используйте класс
final и определите частный конструктор (private), чтобы скрыть общедоступный .
public final class MyValues {
private MyValues() {
}
public static final String VALUE1 = "foo";
public static final String VALUE2 = "bar";
}
18. Добавляйте пустую строку перед аннотацией
@Repository
public class ...
19. Статические поля должны быть размещены в верхней части класса
20. Начиная с Java 8 для обработки типа даты рекомендуется использовать java.handling.java.localDateTime