Подробное объяснение использования Ломбока

Java

предисловиеЧто такое Ломбок?Как установить Ломбок?Подробное объяснение использования ЛомбокаLombok предоставляет методы аннотаций для упрощения кода. Обзор распространенных аннотаций:val@Data@Value@Getter@Setter@Getter(lazy=true)@ToString@EqualsAndHashCode@NonNull@Synchronized@NoArgsConstructor@AllArgsConstructor@RequiredArgsConstructor@Cleanup@Log@Accessors@SneakyThrows@Builder

предисловие

В Java пакет является очень хорошим механизмом, наиболее распространенный пакет включен в метод GET, SET, будь то Intellij IDEA или Eclipse, он предоставляет ярлык для создания метода get, set, который очень удобен в использовании. На самом деле у нас есть более удобные способы, то есть - Lombok: Очень мощный аннотатор POJO.

Что такое Ломбок?

lombok предоставляет простую форму аннотаций, помогающую нам упростить и исключить некоторые обязательные, но раздутые Java-коды. Особенно в отношении POJO.

Как установить Ломбок?

1. Установите через Центр плагинов IntelliJ.

2. Установите плагин

3, в конце необходимо отметить, что при использовании аннотации Lombok я не забываю импортировать в проект пакет Lombok.jar.Если вы используете Maven Project, добавьте зависимости в POM.xml.

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.8</version>
</dependency>

Подробное объяснение использования Ломбока

Lombok предоставляет методы аннотаций для упрощения кода. Обзор распространенных аннотаций:

  • val: используется перед локальными переменными, что эквивалентно объявлению переменной final
  • @Data: Аннотируется на класс; предоставляет методы получения и установки всех свойств класса, а также предоставляет методы equals, canEqual, hashCode, toString, что эквивалентно добавлению следующих аннотаций @Setter @Getter, @ToString, @EqualsAndHashCode в в то же время
  • @Value: используется в классах, это неизменяемая форма @Data, которая эквивалентна добавлению окончательных объявлений к свойствам, предоставляя только методы получения, а не методы установки.
  • @Сеттер, @Геттер: содержит аннотации к классам и свойствам; обеспечивает установку и получение методов для свойств.
  • @Getter(lazy=true): Может заменить классический шаблонный код Double Check Lock.
  • @ToString: Генерация метода toString.По умолчанию выводятся имя класса и все атрибуты.Атрибуты выводятся по порядку, разделенные запятыми.
  • @EqualsAndHashCode: Реализовать метод equals() и метод hashCode().
  • @Builder: режим строителя сборки
  • @NonNull: эта аннотация быстро определяет, пуста ли она, и если она пуста, выдает исключение java.lang.NullPointerException.
  • @Synchronized: Эта аннотация автоматически добавляется в механизм синхронизации.Интересно, что сгенерированный код является не прямым методом блокировки, а блоком кода блокировки, а областью действия является метод
  • @Log: генерировать различные типы объектов журнала в соответствии с различными аннотациями, но все имена экземпляров являются журналами, и существует шесть дополнительных классов реализации.
  • @NoArgsConstructor: аннотируется в классе; создаст статический фабричный метод, возвращающий объект класса.
  • @RequiredArgsConstructor: аннотируется в классе; предоставляет конструктор частичных параметров для класса (используйте все аннотированные или окончательно модифицированные переменные-члены @NonNull в классе для создания соответствующего конструктора)
  • @AllArgsConstructor: аннотируется в классе; предоставляет конструктор с полными параметрами для класса.
  • @Cleanup: используется для обеспечения освобождения выделенных ресурсов, например закрытия соединений ввода-вывода.
  • @SneakyThrows: выбросить исключение
  • @Accessors: используется для настройки сгенерированного результата методов получения и установки.

val

Используется перед локальными переменными, это эквивалентно объявлению переменной как final

public static void main(String[] args) {
    val sets = new HashSet<String>();
    //=>相当于如下
    final Set<String> sets2 = new HashSet<>();
}

@Data

Аннотация находится на классе, она предоставляет методы получения и установки всех свойств класса, а также предоставляет методы equals, canEqual, hashCode, toString, что эквивалентно добавлению следующих аннотаций @Setter @Getter, @ToString, @EqualsAndHashCode в то же время

@Data
public class Person {
    private String name;
    private String address;
    private String city;
    private String state;
    private String zip;
    private Date brithday;
}

Эффект такой же, как показано ниже:

@Value

@Value
@AllArgsConstructor
public class Student {
    private String name ;
    private int age;
    //相当于
    private final int age;
    public int getAge(){
        return this.age;
    }
}

Фактический звонок:

Student student = new Student("hresh",22);//没有set方法
System.out.println(student);
System.out.println(student.getName());

@Getter@Setter

Аннотации к классам и свойствам; предоставление методов установки и получения свойств

public class Person {
    @Getter@Setter
    private String name;
}

Эквивалентно:

public String getName() {
        return name;
    }

public void setName(String name) {
        this.name = name;
}

@Getter(lazy=true)

Если инициализация поля бина является затратной операцией, например загрузкой большого количества данных, то при этом это поле не обязательно используется. Тогда использование механизма ленивой загрузки может гарантировать экономию ресурсов.

Механизм ленивой загрузки заключается в том, что при инициализации объекта поле не инициализируется на самом деле, а инициализируется при первом доступе к полю.

public class GetterLazyExample {
    @Getter(lazy = true)
    private final double[] cached = expensive();
    private double[] expensive() {
        double[] result = new double[1000000];
        for (int i = 0; i < result.length; i++) {
            result[i] = Math.asin(i);
        }
        return result;
    }
}

// 相当于如下所示: 

import java.util.concurrent.atomic.AtomicReference;
public class GetterLazyExample {
    private final AtomicReference<java.lang.Object> cached = new AtomicReference<>();
    public double[] getCached() {
        java.lang.Object value = this.cached.get();
        if (value == null) {
            synchronized (this.cached) {
                value = this.cached.get();
                if (value == null) {
                    final double[] actualValue = expensive();
                    value = actualValue == null ? this.cached : actualValue;
                    this.cached.set(value);
                }
            }
        }
        return (double[]) (value == this.cached ? null : value);
    }
    private double[] expensive() {
        double[] result = new double[1000000];
        for (int i = 0; i < result.length; i++) {
            result[i] = Math.asin(i);
        }
        return result;
    }
}

@ToString

Генерируется метод toString.По умолчанию выводится имя класса и все атрибуты.Атрибуты выводятся по порядку, через запятую. Но следует отметить, что:@ToStringЕсть несколько свойств, которые можно установить дополнительно:

  • callSuperВыводить ли метод toString родительского класса, по умолчанию — false
  • includeFieldNamesВключать ли имя поля, по умолчанию верно
  • excludeИсключить поля, которые генерируют tostring
@ToString(callSuper = true,exclude ={"name"})
public class Person {
    private String name;
    private String address;
}

Эквивалентно:

public String toString() {
 return "Person{" +
                "address='" + address + '\'' +
    '}';
}

@EqualsAndHashCode

Используется в классах для автоматического создания метода equals и метода hashCode.

параметрexcludeисключить некоторые свойства ; параметрыofУказывает, какие свойства только использовать; по умолчанию используются только свойства, определенные в этом классе, а методы суперкласса не вызываются (т. е. callSuper=false).

//父类
public class Person {
    private String name;
    private String sex;

    public Person(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }
}
@EqualsAndHashCode(exclude = {"className"},callSuper = false)
public class Student extends Person{
    @Getter@Setter
    private int age;
    @Getter@Setter
    private String className;

    public Student(String name,String sex,int age,String className) {
        super(name,sex);
        this.age = age;
        this.className = className;
    }
}
Student s1 = new Student("hresh","man",22,"Lv3");
Student s2 = new Student("hresh","woman",22,"Lv5");
System.out.println(s1.equals(s2));//true

Анализ: реализация подкласса@EqualsAndHashCode(callSuper = false), не вызывать свойство родительского класса, то если свойства подкласса совпадают, то и значение хешкода такое же, плюс исключается сравнение свойства className, поэтому возвращаемое значение метода equals из двух объектов в коде верно.

@NonNull

Эта аннотация быстро определяет, пуста ли она, и если она пуста, выдает исключение java.lang.NullPointerException.

public class Person {

    private String name;

    @Setter@Getter@NonNull
    private List<Person> member;
}

Эквивалентно:

@NonNull
private List<Person> members;

public Family(@NonNull final List<Person> members) {
    if (members == null) throw new java.lang.NullPointerException("members");
    this.members = members;
}

@NonNull
public List<Person> getMembers() {
    return members;
}

public void setMembers(@NonNull final List<Person> members) {
    if (members == null) throw new java.lang.NullPointerException("members");
    this.members = members;
}

@Synchronized

Эта аннотация автоматически добавляется в механизм синхронизации.Интересно, что сгенерированный код является не прямым методом блокировки, а блоком кода блокировки, и область видимости находится на методе.

private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");

@Synchronized
public String synchronizedFormat(Date date) {
    return format.format(date);
}

Эквивалентно:

private final java.lang.Object $lock = new java.lang.Object[0];
private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");

public String synchronizedFormat(Date date) {
    synchronized ($lock) {
        return format.format(date);
    }
}

@NoArgsConstructor

Аннотация к классу; предоставляет конструктор без аргументов для класса

@Data
@NoArgsConstructor(staticName = "init")
public class Student {
    private long id = new Long(0);
    private String name = " ";
    private String className = " ";
}

Эквивалентно:

@Data
//@NoArgsConstructor(staticName = "init")
public class Student {
    private long id = new Long(0);
    private String name = " ";
    private String className = " ";

    public static Student init(){
        return new Student();
    }
}

При вызове:

public class StudentTest {
    public static void main(String[] args) {
//        Student student = new Student();//编译时报错
        Student student = Student.init();
        student.setName("hresh");
        student.setClassName("Lv5");
        System.out.println(student);
    }
}

@AllArgsConstructor

Аннотируется в классе, чтобы предоставить конструктор с полными параметрами для класса.

@Data
@AllArgsConstructor
public class Student {
    private long id = new Long(0);
    private String name = " ";
    private String className = " ";
}

эквивалентно:

@Data
public class Student {
    private long id = new Long(0);
    private String name = " ";
    private String className = " ";

    public Student(long id, String name, String className) {
        this.id = id;
        this.name = name;
        this.className = className;
    }
}

@RequiredArgsConstructor

@Data
@RequiredArgsConstructor
public class Student {
    @NonNull
    private long id ;
    @NonNull
    private String name ;
    private String className;

}

Фактический звонок:

Student student = new Student(101,"hresh");
System.out.println(student);

@Cleanup

Аннотации можно использовать для обеспечения освобождения выделенных ресурсов, таких как закрытие соединения ввода-вывода.

public void testCleanUp() {
    try {
        @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write(new byte[] {'Y','e','s'});
        System.out.println(baos.toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Эквивалентно:

public void testCleanUp() {
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            baos.write(new byte[]{'Y', 'e', 's'});
            System.out.println(baos.toString());
        } finally {
            baos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Log

@CommonsLog Creates log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);

@Log Creates log = java.util.logging.Logger.getLogger(LogExample.class.getName());

@Log4j Creates log = org.apache.log4j.Logger.getLogger(LogExample.class);

@Log4j2 Creates log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);

@Slf4j Creates log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

@XSlf4j Creates log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

Чаще всего я использую объект журнала slf4j.

Аннотация находится в классе; предоставьте классу объект журнала slf4j со свойством с именем log

@Slf4j
public class StudentTest {

    public static void main(String[] args) {
        log.info("Here is some INFO");
    }
}

Эквивалентно:

public class StudentTest {

    public static Logger log = LoggerFactory.getLogger(StudentTest.class);

    public static void main(String[] args) {
        log.info("Here is some INFO");
    }
}

@Accessors

Аксессор в китайском означает аксессор,@AccessorsГенерация результатов для настройки методов получения и установки, три свойства, описанные ниже:

1. Свободно

По-китайски fluent означает fluent.Если для него задано значение true, сгенерированный метод get/set не имеет префикса set/get, а значение по умолчанию — false .

@Data
@Accessors(fluent = true)
public class Student {
    private long id = new Long(0);
    private String name = " ";
    private String className = " ";

}

фактический вызов

public class StudentTest {

    public static void main(String[] args) {
        Student student = new Student();
        student.name("hresh");//相当于SetName()
        student.className("Lv5");
        System.out.println(student);
        System.out.println(student.name());//相当于getName()
    }
}

2. цепь

Цепочка в китайском языке означает цепочку, которая является логическим значением.Если метод set, сгенерированный для true, возвращает это, то метод set, сгенерированный для false, имеет тип void. По умолчанию false, за исключением случаев, когда fluent имеет значение true, цепочка по умолчанию имеет значение true .

@Data
@Accessors(chain = true)
public class Student {
    private long id = new Long(0);
    private String name = " ";
    private String className = " ";

}

Фактический звонок:

public class StudentTest {

    public static void main(String[] args) {
        Student student = new Student();

        Student student1 = student.setClassName("Lv5");
        System.out.println(student);
        System.out.println(student1);
    }
}

3. префикс

префикс представляет собой серию строковых типов, вы можете указать префикс, и указанный префикс будет удален при генерации метода get/set.

@Data
@Accessors(prefix = "n")
public class Student {
//    private long id = new Long(0);
    private String nAme = " ";
    private String name = " ";
    private String className = " ";
    private int nId  = new Integer(0);
}

Фактический звонок:

public class StudentTest {

    public static void main(String[] args) {
        Student student = new Student();

        student.setId(101);
        System.out.println(student.getId());
        student.setAme("hresh");
        student.setName("hresh");
        System.out.println(student);
    }
}

Следует отметить, что в настоящее время существует такое правило для именования атрибутов в классе, указание префикса + символы верхнего регистра, как в приведенном выше коде, если для атрибута указано имя вместо nAme, оно не выполняется.

@SneakyThrows

Автоматически создавать проверенные исключения без явного использования оператора throws в методе.

@SneakyThrows
public void read(){
    InputStream inputStream = new FileInputStream("");
}
//相当于
public void read() throws FileNotFoundException {
    InputStream inputStream = new FileInputStream("");
}

@Builder

Используется в классах, конструкторах и методах, чтобы предоставить вам сложные API-интерфейсы конструктора.

@Builder
@Data
public class Student {
    private String name ;
    private int age;
}

Фактический звонок:

public class StudentTest {

    public static void main(String[] args) {
        Student student = Student.builder().name("hresh").age(22).build();
    }
}

Эквивалентно:

public class Student {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public static Builder builder(){
        return new Builder();
    }
    public static class Builder{
        private String name;
        private int age;
        public Builder name(String name){
            this.name = name;
            return this;
        }

        public Builder age(int age){
            this.age = age;
            return this;
        }

        public Student build(){
            Student student = new Student();
            student.setAge(age);
            student.setName(name);
            return student;
        }
    }
}