Java-разработка Ломбока должна знать, должна знать

Java

公众号

1. Введение

Среди многих языков программирования в настоящее время производительность языка Java по-прежнему привлекает внимание.Будь то разработка сервера корпоративного уровня или разработка клиента Andorid, он является первым выбором в качестве языка разработки.Даже в области больших разработка данных, язык Java также может занять место, например, Hadoop, Spark, большие данные Flink и т. д. По сравнению с другими языками, Java, который родился 24 года назад, немного утомителен и сложен в написании.Чтобы значительно повысить эффективность и простоту разработки на Java, родилась библиотека Java Lombok.

Прежде всего, давайте взглянем на официальное описание Ломбока:

Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.

Из приведенного выше описания мы можем получить предварительное представление о Lombok, библиотеке Java для редакторов и инструментов сборки, которые могут улучшать написанный код Java, например, без написания классов сущностей.getterметод,equalsВместо этого метод генерируется автоматически, автоматически генерируя выходные переменные журнала и т. д., сокращая код повторяющихся шаблонов. После приблизительного знакомства с функциями, предоставляемыми инфраструктурой Lombok, давайте действительно воспользуемся аннотациями, предоставленными Lombok, чтобы увидеть, как они могут помочь нам улучшить простоту и эффективность написания кода Java.

Основное содержание этой статьи следующее:

  • Установка плагина Ломбок
  • Общее использование аннотаций Ломбока

Пример проекта:GitHub.com/ Как будто впервые увидел 12138…

  • ломбок-действия:

Экологическая поддержка:

  • JDK 8
  • SpringBoot 2.1.4
  • Maven 3.6.0

2. Текст

2.1 Установить Ломбок

Прежде чем использовать Lombok, нам необходимо выполнить комплексную установку в используемой нами среде IDE.На примере IDEA шаги установки очень просты:

  • перейти кFile -> Settings -> Plugin -> Marketplace, поиск Ломбок

    image-20190602193640583

  • Выберите результат поиска Lombok и нажмите «Установить».

  • После завершения установки перезапустите.

Способ установки Lombok-плагина на основе Eclipse здесь подробно не описывается, а официал также дает соответствующую документацию:проект Lombok.org/setup/Российские Продукты Процессинга…

После установки плагина Lombok в IDE мы можемpom.xmlДобавьте зависимости Lombok в файл для использования.

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
    <scope>provided</scope>
</dependency>

Уведомление:pomЗависимость устанавливает область действияprovided, чтобы библиотека Lombok не была запакована в программу.

2.2 @Getter/@Setter

Обычно, независимо от того, сколько полей мы пишем в классе сущностей, мы должны обеспечить егоgetterиsetterметоды, как в примере класса нижеUser.java

image-20190602195006495

Мы часто сталкиваемся с такой ситуацией: чтобы добавить и изменить поле в классе сущностей, нам всем нужно заниматься настройкой отдельно, что очень хлопотно и повторяется. В настоящее время, если мы используем Lombok для предоставления@Getter/@SetterАннотации могут помочь нам сохранить геттеры иsetterСопровождение методов, ЛомбокUserкласс сгенерирован автоматическиgetterиsetterметод, окончательный байт-код обоих одинаковый, и теперь мы находимся вUser.javaКод, написанный выше, состоит всего из 7 строк:

@Getter
@Setter
public class User {
    private Integer id;
    private String username;
    private String password;
}

Затем используйте тестовый классUserTests.javaРезультаты теста следующие:

public class UserTests {
    @Test
    public void test() {
        User user = new User();
        user.setUsername("one");
        user.setPassword("zxc123");
        Assert.assertEquals(user.getUsername(), "one");
        Assert.assertEquals(user.getPassword(), "zxc123");
    }
}

@Getter/@SetterАннотации можно использовать не только на классах, но и на полях, а это значит, что они автоматически генерируются для поляgetter /setterметод.

@Getter
@Setter
private String password;

Разница между тем, используется ли аннотация для класса или поля, заключается в том, что если аннотация используется для класса, она действительна только для нестатических полей этого класса.

Следует отметить, что если@GetterАннотация изменяетbooleanпеременная типа, сгенерированнаяgetterСигнатура методаisXXXформу, а неgetXXXформа.

Кроме,@Getter/@SetterТакже предоставляет свойства для управления доступомlombok.AccessLevel value(), По умолчаниюPUBLIC, в то время как другие параметры являются типами перечисления:MODULE, PROTECTED, PACKAGE, PRIVATE

2.3 @NonNull

Как следует из названия,@NonNullиспользуется для обозначения классов, которые не могут бытьnullПоле или параметры в любом месте генерирует код оценки поля нулевого указателя, если@NonNullОтмеченная переменная имеет значение null, выдаетNullPointException(NPE) Исключение. Например, следующий пример кода:

public class User {
    private Integer id;
    private String username;
    private String password;

    public User(Integer id, @NonNull String username, @NonNull String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
}

использовал@NonNullПосле аннотации мы можем получить информацию о байт-коде после декомпиляции следующим образом, это окончательный код, сгенерированный Lombok:

public class User {
    private Integer id;
    private String username;
    private String password;

    public User(Integer id, @NonNull String username, @NonNull String password) {
        if (username == null) {
            throw new NullPointerException("username is marked non-null but is null");
        } else if (password == null) {
            throw new NullPointerException("password is marked non-null but is null");
        } else {
            this.id = id;
            this.username = username;
            this.password = password;
        }
    }
}

2.4 Аннотации конструктора

Давайте посмотрим на сцены, которые часто встречаются при написании методов конструктора для классов сущностей. Ломбок предоставляет три разных аннотации конструктора.@NoArgsConstructor / @AllArgsConstructor / @RequiredArgsConstructorМетоды обработки различных методов конструктора будут описаны один за другим.

  • @NoArgsConstructorСоздание метода конструктора класса сущности без параметров

  • @AllArgsConstructorГенерируется для классов сущности, кромеstaticМетод конструктора с параметрами вне декорированного поля.

  • @RequiredArgsConstructorМетоды конструктора, которые генерируют определенные поля для классов сущностей, которые необходимоfinal,или@NonNullретушь.

    ```java
      @RequiredArgsConstructor
      public class User3 {
          private Integer id;
          private final String username;
          @NonNull
          private String password;
      }
    ```
    

    Этот эффект компилируется с помощью метода конструктора успешно:User3 user3 = new User3("user3", "zxc123");

2.5 @ToString

@ToStringКласс будет автоматически генерировать легко читаемыйtoStringметод, с именами свойств и значениями некоторых нестатических полей, что очень удобно для операций печати в нашей повседневной разработке.

@Getter
@Setter
@AllArgsConstructor
@ToString
public class User2 {
    private Integer id;
    private String username;
    private String password;
}

Наконец, скомпилированный в байт-код, результаты декомпиляции выглядят следующим образом:

public class User2 {
    private Integer id;
    private String username;
    private String password;
    // 省去 setter/getter
    public String toString() {
        return "User2(id=" + this.getId() + ", username=" + this.getUsername() + ", password=" + this.getPassword() + ")";
    }
}

Кроме того, обратите внимание@ToStringТакже поддерживает настройку вывода журнала, указывающую, какие поля и какие не должны отображаться вtoStringметод. использовать атрибут@ToString.ExcludeИсключатьtoStringПоявляется в поле с помощью@ToString.IncludeТег должен появиться вtoStringПоля в , см. пример для конкретного использования:

@Getter
@Setter
@AllArgsConstructor
@ToString
public class User2 {
    @ToString.Exclude
    private Integer id;
    @ToString.Include
    private String username;
    @ToString.Include
    private String password;
}

РаспечататьUser2Эффект журнала объекта:User2(username=user2, password=zcx123).

2.6 @EqualsAndHashCode

@EqualsAndHashCodeАннотации используются для автоматического переопределения нестатических полей, принадлежащих классу.equals方法和 hashCode 方法,方便我们用于对象间的比较。 похожий@ToString,@EqualsAndHashCodeВы также можете использовать поля, которые необходимо сравнивать, и исключать поля, которые не нужно сравнивать. Для конкретного использования см. следующий пример:

@Getter
@Setter
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class User4 {
    @EqualsAndHashCode.Exclude
    private Integer id;
    @EqualsAndHashCode.Include
    private String username;
    @EqualsAndHashCode.Exclude
    private String password;
}

После написания кода класса сущностей мы пишем тестовый метод, чтобы попробовать эффект:

@Test
public void testEqual() {
    User4 user4 = new User4(1, "user4", "zxc");
    User4 user4_2 = new User4(1, "user4", "123");
    Assert.assertEquals(user4, user4_2); // ture
}

2.7 @Data/@Value

@Data/@ValueАннотация, обеспечивающая более полную функцию генерации кода, эквивалентную следующим аннотациям.

@Getter
@Setter
@RequiredArgsConstructor
@ToString
@EqualsAndHashCode

Обе аннотации можно использовать только в классах с@Dataразные,@ValueИспользуется для украшения неизменяемых классов. Если общий класс сущностей не имеет особых ограничений, его обычно можно использовать напрямую.@DataМодификация аннотации.

2.8 @Builder

@Builder是一个非常强大的注解,提供了一种基于建造者模式的构建对象的 API。 использовать@BuilderАннотации автоматически генерируются для наших классов сущностей.builder()метод и назначьте поле непосредственно в соответствии с методом имени поля и, наконец, используйтеbuild()метод создания объекта сущности.

@Data
@Builder
public class User6 {
    private Integer id;
    private String username;
    private String password;
}

@Test
public void testBuilder() {
    User6 user6 = User6.builder().id(1).username("user6").password("zxc123").build();
    log.warn("testLog: {}", user6); // User6(id=1, username=user6, password=zxc123)
}

должен быть в курсе@BuilderГенерация полей родительского класса не поддерживается.Если у класса сущностей есть родительский класс,@BuilderГенерировать только поля текущего метода построения класса. Если необходимо использовать метод поля родительского класса, Ломбок предлагает новый комментарий@SuperBuilderЧтобы справиться с этой ситуацией, необходимо следующее.@SuperBuilderКак использовать аннотации:

@SuperBuilder
@Getter
@Setter
public class Parent {
   private int id;
   private String name;
}

@SuperBuilder
@Data
public class Child extends Parent {
    private String childName;
}

Пример вызова:

Child child = Child.builder().id(1).name("父类名称").childName("子类名称").build();
System.out.println(child.getId());

Поскольку плагин Lombok не был обновлен для поддержки@SuperBuilder, поэтому написанное выше также вызовет ошибку компиляции в IDEA, которую невозможно найтиbuilder()метод.

Вы также можете обратиться к этой статье, чтобы разобраться в случае наследования:Рейнхард.codes/2015/09/16/...

2.9 Аннотации журнала

Для общих различных объектов Logger в классах программ Lombok также предоставляет аннотации для автоматического создания объектов Logger и элегантного вывода журналов, просто используйте аннотации журнала в классе, например@Log. Конечно, Lombok поддерживает несколько фреймворков ведения журналов и предоставляет соответствующие аннотации следующим образом:

  • @CommonsLogЭквивалентный эффект:private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);

  • @FloggerЭквивалентный эффект:private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();

  • @JBosLogЭквивалентный эффект:private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);

  • @LogЭквивалентный эффект:private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());

  • @Log4jЭквивалентный эффект:private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);

  • @Log4j2Эквивалентный эффект:private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);

  • @Slf4jЭквивалентный эффект:private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

  • @XSlf4jЭквивалентный эффект:private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

Используйте следующий код@Slf4jАннотация для вывода журнала:

@Slf4j
public class UserTests {
    // ....
    @Test
    public void testLog() {
        User5 user5 = new User5();
        user5.setId(1);
        user5.setUsername("user5");
        user5.setPassword("zxc123");
        log.warn("testLog: {}", user5);
   // 21:57:15.488 [main] WARN com.one.learn.lombok.UserTests - testLog: User5(id=1, username=user5, password=zxc123)
    }
}

2.10 @Cleanup

@CleanupИспользуется для пометки переменных объекта ресурсов, которые необходимо освободить для операций очистки, таких какFileInputStream, FileOutputStreamИ так, после пометки ресурсных объектов израсходованными, он будет автоматически остановлен и очищен, собственно, здесь Ломбок добивается результатов и характеристик Java7try with resourceНапример, для нас, чтобы защитить закрытый ресурс, код шаблона приведен ниже.@CleanupПример использования:

public class CleanupExample {
    public static void main(String[] args) throws IOException {
        @Cleanup InputStream in = new FileInputStream(args[0]);
        @Cleanup OutputStream out = new FileOutputStream(args[1]);
        byte[] b = new byte[10000];
        while (true) {
            int r = in.read(b);
            if (r == -1) {
                break;
            }
            out.write(b, 0, r);
        }
    }
}

будетCleanupExample.javaДекомпиляция сгенерированного байт-кода дает следующие результаты:

public class CleanupExample {
    //...
    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream(args[0]);
        try {
            FileOutputStream out = new FileOutputStream(args[1]);
            try {
                byte[] b = new byte[10000];
                while(true) {
                    int r = in.read(b);
                    if (r == -1) {
                        return;
                    }
                    out.write(b, 0, r);
                }
            } finally {
                if (Collections.singletonList(out).get(0) != null) {
                    out.close();
                }
            }
        } finally {
            if (Collections.singletonList(in).get(0) != null) {
                in.close();
            }
        }
    }
}

2.11 @SneakyThrows

@SneakyThrowsВ основном используется, когда нетthrowsВ случае ключевого слова проверяемое исключение выбрасывается скрытно, что опускается, когда нам нужно выбрасывать исключение в нашей обычной разработке.throwОперация, ниже@SneakyThrowsпример кода:

public class SneakyThrowsExample implements Runnable {
  @SneakyThrows(UnsupportedEncodingException.class)
  public String utf8ToString(byte[] bytes) {
    return new String(bytes, "UTF-8");
  }

  @SneakyThrows
  public void run() {
    throw new Throwable();
  }
}

Наконец, скомпилированный в байт-код, результаты декомпиляции выглядят следующим образом:

public class SneakyThrowsExample implements Runnable {
    public SneakyThrowsExample() {
    }

    public String utf8ToString(byte[] bytes) {
        try {
            return new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException var3) {
            throw var3;
        }
    }

    public void run() {
        try {
            throw new Throwable();
        } catch (Throwable var2) {
            throw var2;
        }
    }
}

2.12 val/var

val/varОна используется для модификации локальных переменных.При такой модификации аннотации тип переменной будет автоматически выводиться из выражения справа от знака равенства.Эта функция заимствована из функции автоматического определения типа многих языков программирования. . иvalиvarРазница в том, чтоvalИспользуется для декорирования неизменяемых переменных, var украшает изменяемые переменные. когдаvalКогда измененная переменная переназначается, компилятор выдаст исключение:Error: java: 无法为最终变量 X 分配值.实际用法也比较简单,可参考下面代码:

@Slf4j
public class VarValExample {
    public static void main(String[] args) {
        val text = "abc";
        // text = "1"; // Error: java: 无法为最终变量 text 分配值`。
        var num = 1;
        num = 2;
        log.info("text:{},num:{}", text, num); // text:abc,num:2
    }
}

3. Заключение

На данный момент мы изучили около 80% часто используемых аннотаций Ломбока, которых более чем достаточно для нашей ежедневной разработки Давайте попробуем использовать Ломбок, и постепенно вы почувствуете улучшение эффективности и элегантности кода.

Если вы чувствуете, что получили что-то после прочтения, нажмите [Хорошо выглядит], нажмите на изображение заголовка статьи и отсканируйте код, чтобы подписаться на [технический блог Венрена] 😄😄😄.

4. Ссылка