20 советов для java-разработчиков

Некоторые из важнейших советов для java-разработчиков, которые помогут вам повысить качество вашего кода.

1-Отдавайте предпочтение примитивам, а не классам-оболочкам, когда это возможно.

Long idNumber;
long idNumber; // long takes less memory than Long

2-Попробуйте использовать подходящий тип для ваших переменных.
Если два или более типа данных удовлетворяют ваши функциональные потребностям, используйте тот, который занимает меньше места в памяти.

int birthYear;
short birthYear; // better because birth year can not be more than 32767


int personRunningSpeedKmHour;
byte personRunningSpeedKmHour; // better because a person can not have
// more than 127 km/h as speed

3- Для проверки нечётности числа побитовый оператор AND выполняется намного быстрее, чем арифметический оператор по модулю.

public boolean isOdd(int num) {
return (num & 1) != 0;
} 
// best way to check the oddity of a number

4-Избегайте избыточной инициализации (0, false, null..)
Например, boolean,  по-умолчанию, имеет значение false, поэтому не стоит излишне его инициализировать .

String name = null; // redundant
int speed = 0; // redundant
boolean isOpen = false; // redundant


String name; 
int speed;
boolean isOpen;
// same values in a cleaner way

5-Объявляйте членов класса private везде, где это возможно, и всегда указывайте модификатор наиболее ограниченного доступа.

public int age; // very bad
int age; // bad
private int age; // good

6-Избегайте использования ключевого слова ‘new’ при создании строки.

String s1 = new String("AnyString") ; // bad : low instantiation
// The constructor creates a new object, and adds the literal to the heap


String s2 = "AnyString" ; // good: fast instantiation
// This shortcut refers to the item in the String pool 
// and creates a new object only if the literal is not in the String pool.

7-Для объединения нескольких строк используйте StringBuilder или StringBuffer вместо использования оператора +.
Оператор + неэффективен, поскольку компилятор java создаёт несколько промежуточных строковых объектов перед созданием окончательной объединённой строки.
StringBuilder или StringBuffer изменяют строку без создания промежуточных строковых объектов.

String address = streetNumber +" "+ streetName +" "
+cityName+" "+cityNumber+" "+ countryName; // bad


StringBuilder address = new StringBuilder(streetNumber).append(" ")
.append(streetName).append(" ").append(cityName).append(" ")
.append(cityNumber).append(" ").append(countryName); // good

8-Используйте символы подчёркивания в числовых литералах.

int myMoneyInBank = 58356823;
int myMoneyInBank = 58_356_823; // more readable

long billsToPay = 1000000000L;
long billsToPay = 1_000_000_000L; // more readable

9-Избегайте использования циклов for с index.
Не используйте цикл for с переменной index (или counter), если вы можете заменить его расширенным циклом for (начиная с Java 5) или forEach (начиная с Java 8). Это потому, что переменная index подвержена ошибкам, так как мы можем случайно изменить её в теле цикла, или мы можем начать индекс с 1 вместо 0.

for (int i = 0; i < names.length; i++) 
{ saveInDb(names[i]); }


for (String name : names) 
{ saveInDb(name); } // cleaner

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();}}
// error-prone as we can forget to close the scanner in the finally block



try (Scanner scanner = new Scanner(new File("test.txt"))) 
{while (scanner.hasNext()) 
{System.out.println(scanner.nextLine());}} 
catch (FileNotFoundException fnfe) 
{fnfe.printStackTrace();} 
// cleaner and more succinct

11-Отсутствие свободных блоков захвата.
Пустой блок catch приведёт к молчаливому завершению программы и не даст никакой информации о том, что пошло не так.

try
{ productPrice = Integer.parseInt(integer); } 
catch (NumberFormatException ex)
{ } 
// fail silently without giving any feedback


try 
{ productPrice = Integer.parseInt(integer); } 
catch (NumberFormatException ex) 
{unreadablePrices.add(productPrice); // handle error
log.error("Cannot read price : ", productPrice );// proper and meaningful message
}

12-Избегайте исключения нулевого указателя, насколько это возможно.
Постарайтесь избежать исключений с нулевым указателем, которые могут возникать во время выполнения, с помощью:

  • Возврата пустых коллекций вместо возврата нулевых элементов
  • Использования Optional , если это возможно
  • методов requireNonNull в java.utils.Objects
  • Аннотаций NotNull, NotEmpty, NotBlank
  • Objects::nonNull в Streams
  • методов requireNonNull в java.util.Objects

13-Добавляйте только необходимые геттеры, сеттеры и конструкторы и избегайте Lombok (YAGNI).
Добавляйте только тот код, который вам нужен.
Lombok – отличный инструмент, который может помочь вам сгенерировать некоторый шаблонный код, но у него есть некоторые недостатки, такие как несовместимость IDE, использование непубличного API и он тесно связан с компилятором java. Кроме того, начиная с java 14, records может заменить некоторые из его утилит.

14-Чтобы проверить равенство, используйте == для ссылок и equals для объектов.

// prerequisite:  the person class overrides equals() and hashCode()
Person p1 = new Person("John","Doe");
Person p2 = new Person("John","Doe");

System.out.println(p1 == p2); // false
System.out.println(p1.equals(p2)); // true

Вы можете ознакомиться с более подробной информацией по этому вопросу здесь

15-Всегда осуществляйте hashCode , когда вы используете equals.
Всегда помните о переопределении hashCode , если вы используете equals.
Согласно API, результат, возвращаемый методом hashCode() для двух объектов, должен быть одинаковым, если их методы equals показывают, что они эквивалентны.

16-Предпочитайте records (начиная с java14) для неизменяемых данных.

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);
    }
}



// this class can be transformed to a record:
record Person(String name, long idNumber) { } // cleaner and less verbose

17-Для констант используйте enum или final class вместо interface.

public final class MyValues {
  private MyValues() {
    // No need to instantiate the class, we can hide its constructor
  }
  public static final String VALUE1 = "foo";
  public static final String VALUE2 = "bar";
}

18-Добавляйте пустую строку перед аннотацией.

            // <-- empty line
@Repository
public class ...

19-Статические поля должны быть размещены в верхней части класса.

20-Для обработки типа даты рекомендуется java.handling.java.LocalDateTime начиная с java 8.

Чтобы ознакомиться с другими передовыми практиками java, я рекомендую эти замечательные книги: ” Clean code” и “Effective java“.

+1
1
+1
10
+1
0
+1
2
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *