资讯专栏INFORMATION COLUMN

lombok:推荐使用的编译时Getter/Setter等类似代码生成库

dance / 3332人阅读

摘要:每个用的孩子都应该了解下主要依赖编译时代码生成技术,帮你自动生成基于模板的常用的代码,譬如最常见的与。另一种是通过类似于这样基于注解的在运行时利用反射动态添加,不过这样的缺陷是会影响性能,并且有一定局限性。

Lombok

每个用Java的孩子都应该了解下Lombok

Lombok主要依赖编译时代码生成技术,帮你自动生成基于模板的常用的Java代码,譬如最常见的Getter与Setter。之前动态的插入Getter与Setter主要有两种,一个是像Intellij与Eclipse这样在开发时动态插入,缺点是这样虽然不用你手动写,但是还是会让你的代码异常的冗长。另一种是通过类似于Spring这样基于注解的在运行时利用反射动态添加,不过这样的缺陷是会影响性能,并且有一定局限性。

文章的Github Repo
部分测试代码参考这里

Quick Start Installation

笔者目前用的开发环境是Intellij+Gradle,这里只介绍下这种搭建方式,其他的基于Eclipse或者Maven的可以到官网主页查看。

(1)在Intellij中添加Plugin

Go to File > Settings > Plugins

Click on Browse repositories...

Search for Lombok Plugin

Click on Install plugin

Restart Android Studio

(2)允许注解处理

Settings -> Compiler -> Annotation Processors

(3)Gradle中添加依赖

compile "org.projectlombok:lombok:1.12.6"
动态类型推导 Data Model:数据模型 Getter&Setter

源代码:

import lombok.AccessLevel;

import lombok.Getter;

import lombok.Setter;



public class GetterSetterExample {

    /**

     * Age of the person. Water is wet.

     * 

     * @param age New value for this person"s age. Sky is blue.

     * @return The current value of this person"s age. Circles are round.

     */

    @Getter @Setter private int age = 10;

    

    /**

     * Name of the person.

     * -- SETTER --

     * Changes the name of this person.

     * 

     * @param name The new value.

     */

    @Setter(AccessLevel.PROTECTED) private String name;

    

    @Override public String toString() {

        return String.format("%s (age: %d)", name, age);

    }

}

编译之后的代码:



public class GetterSetterExample {

    /**

     * Age of the person. Water is wet.

     */

    private int age = 10;



    /**

     * Name of the person.

     */

    private String name;

    

    @Override public String toString() {

        return String.format("%s (age: %d)", name, age);

    }

    

    /**

     * Age of the person. Water is wet.

     *

     * @return The current value of this person"s age. Circles are round.

     */

    public int getAge() {

        return age;

    }

    

    /**

     * Age of the person. Water is wet.

     *

     * @param age New value for this person"s age. Sky is blue.

     */

    public void setAge(int age) {

        this.age = age;

    }

    

    /**

     * Changes the name of this person.

     *

     * @param name The new value.

     */

    protected void setName(String name) {

        this.name = name;

    }

}
Lazy Getter

源代码:

import lombok.Getter;



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;

    }

}

编译之后:

public class GetterSetterExample {

    /**

     * Age of the person. Water is wet.

     */

    private int age = 10;



    /**

     * Name of the person.

     */

    private String name;

    

    @Override public String toString() {

        return String.format("%s (age: %d)", name, age);

    }

    

    /**

     * Age of the person. Water is wet.

     *

     * @return The current value of this person"s age. Circles are round.

     */

    public int getAge() {

        return age;

    }

    

    /**

     * Age of the person. Water is wet.

     *

     * @param age New value for this person"s age. Sky is blue.

     */

    public void setAge(int age) {

        this.age = age;

    }

    

    /**

     * Changes the name of this person.

     *

     * @param name The new value.

     */

    protected void setName(String name) {

        this.name = name;

    }

}
Data

源代码:

import lombok.AccessLevel;

import lombok.Setter;

import lombok.Data;

import lombok.ToString;



@Data public class DataExample {

    private final String name;

    @Setter(AccessLevel.PACKAGE) private int age;

    private double score;

    private String[] tags;

    

    @ToString(includeFieldNames=true)

    @Data(staticConstructor="of")

    public static class Exercise {

        private final String name;

        private final T value;

    }

}

编译后:

import java.util.Arrays;



public class DataExample {

    private final String name;

    private int age;

    private double score;

    private String[] tags;

    

    public DataExample(String name) {

        this.name = name;

    }

    

    public String getName() {

        return this.name;

    }

    

    void setAge(int age) {

        this.age = age;

    }

    

    public int getAge() {

        return this.age;

    }

    

    public void setScore(double score) {

        this.score = score;

    }

    

    public double getScore() {

        return this.score;

    }

    

    public String[] getTags() {

        return this.tags;

    }

    

    public void setTags(String[] tags) {

        this.tags = tags;

    }

    

    @Override public String toString() {

        return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";

    }

    

    protected boolean canEqual(Object other) {

        return other instanceof DataExample;

    }

    

    @Override public boolean equals(Object o) {

        if (o == this) return true;

        if (!(o instanceof DataExample)) return false;

        DataExample other = (DataExample) o;

        if (!other.canEqual((Object)this)) return false;

        if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;

        if (this.getAge() != other.getAge()) return false;

        if (Double.compare(this.getScore(), other.getScore()) != 0) return false;

        if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;

        return true;

    }

    

    @Override public int hashCode() {

        final int PRIME = 59;

        int result = 1;

        final long temp1 = Double.doubleToLongBits(this.getScore());

        result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());

        result = (result*PRIME) + this.getAge();

        result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));

        result = (result*PRIME) + Arrays.deepHashCode(this.getTags());

        return result;

    }

    

    public static class Exercise {

        private final String name;

        private final T value;

        

        private Exercise(String name, T value) {

            this.name = name;

            this.value = value;

        }

        

        public static  Exercise of(String name, T value) {

            return new Exercise(name, value);

        }

        

        public String getName() {

            return this.name;

        }

        

        public T getValue() {

            return this.value;

        }

        

        @Override public String toString() {

            return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";

        }

        

        protected boolean canEqual(Object other) {

            return other instanceof Exercise;

        }

        

        @Override public boolean equals(Object o) {

            if (o == this) return true;

            if (!(o instanceof Exercise)) return false;

            Exercise other = (Exercise) o;

            if (!other.canEqual((Object)this)) return false;

            if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;

            if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;

            return true;

        }

        

        @Override public int hashCode() {

            final int PRIME = 59;

            int result = 1;

            result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());

            result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode());

            return result;

        }

    }

}
Object Constructor

源代码

import lombok.AccessLevel;

import lombok.RequiredArgsConstructor;

import lombok.AllArgsConstructor;

import lombok.NonNull;



@RequiredArgsConstructor(staticName = "of")

@AllArgsConstructor(access = AccessLevel.PROTECTED)

public class ConstructorExample {

    private int x, y;

    @NonNull private T description;

    

    @NoArgsConstructor

    public static class NoArgsExample {

        @NonNull private String field;

    }

}

编译之后:

public class ConstructorExample {

    private int x, y;

    @NonNull private T description;

    

    private ConstructorExample(T description) {

        if (description == null) throw new NullPointerException("description");

        this.description = description;

    }

    

    public static  ConstructorExample of(T description) {

        return new ConstructorExample(description);

    }

    

    @java.beans.ConstructorProperties({"x", "y", "description"})

    protected ConstructorExample(int x, int y, T description) {

        if (description == null) throw new NullPointerException("description");

        this.x = x;

        this.y = y;

        this.description = description;

    }

    

    public static class NoArgsExample {

        @NonNull private String field;

        

        public NoArgsExample() {

        }

    }

}
Builder

源代码:

package wx.toolkits.basic.class_object.utils.lombok.object;

import lombok.experimental.Builder;

import java.util.Set;

@Builder
public class BuilderExample {
    private String name;
    private int age;
    private Set occupations;

    public static void main(String args[]) {

        BuilderExample builderExample = BuilderExample.builder().build();

    }

}

编译之后的源代码:

import java.util.Set;



public class BuilderExample {

    private String name;

    private int age;

    private Set occupations;

    

    BuilderExample(String name, int age, Set occupations) {

        this.name = name;

        this.age = age;

        this.occupations = occupations;

}

    

    public static BuilderExampleBuilder builder() {

        return new BuilderExampleBuilder();

    }

    

    public static class BuilderExampleBuilder {

        private String name;

        private int age;

        private java.util.ArrayList occupations;

        

        BuilderExampleBuilder() {

        }

        

        public BuilderExampleBuilder name(String name) {

            this.name = name;

            return this;

        }

        

        public BuilderExampleBuilder age(int age) {

            this.age = age;

            return this;

        }

        

        public BuilderExampleBuilder occupation(String occupation) {

            if (this.occupations == null) {

                this.occupations = new java.util.ArrayList();

            }

            

            this.occupations.add(occupation);

            return this;

        }

        

        public BuilderExampleBuilder occupations(Collection occupations) {

            if (this.occupations == null) {

                this.occupations = new java.util.ArrayList();

            }



            this.occupations.addAll(occupations);

            return this;

        }

        

        public BuilderExampleBuilder clearOccupations() {

            if (this.occupations != null) {

                this.occupations.clear();

            }

            

            return this;

        }



        public BuilderExample build() {

            // complicated switch statement to produce a compact properly sized immutable set omitted.

            // go to https://projectlombok.org/features/Singular-snippet.html to see it.

            Set occupations = ...;

            return new BuilderExample(name, age, occupations);

        }

        

        @java.lang.Override

        public String toString() {

            return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";

        }

    }

}
Exception:异常处理 NonNull

源代码:

import lombok.NonNull;



public class NonNullExample extends Something {

    private String name;

    

    public NonNullExample(@NonNull Person person) {

        super("Hello");

        this.name = person.getName();

    }

}

编译之后:

import lombok.NonNull;



public class NonNullExample extends Something {

    private String name;

    

    public NonNullExample(@NonNull Person person) {

        super("Hello");

        if (person == null) {

            throw new NullPointerException("person");

        }

        this.name = person.getName();

    }

}
SneakyThrows

源代码:

import lombok.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();

    }

}

编译之后:

import lombok.Lombok;



public class SneakyThrowsExample implements Runnable {

    public String utf8ToString(byte[] bytes) {

        try {

            return new String(bytes, "UTF-8");

        } catch (UnsupportedEncodingException e) {

            throw Lombok.sneakyThrow(e);

        }

    }

    

    public void run() {

        try {

            throw new Throwable();

        } catch (Throwable t) {

            throw Lombok.sneakyThrow(t);

        }

    }

}
Thread:线程 Synchronized

源代码:

import lombok.Synchronized;



public class SynchronizedExample {

    private final Object readLock = new Object();

    

    @Synchronized

    public static void hello() {

        System.out.println("world");

    }

    

    @Synchronized

    public int answerToLife() {

        return 42;

    }

    

    @Synchronized("readLock")

    public void foo() {

        System.out.println("bar");

    }

}

编译之后:

public class SynchronizedExample {

    private static final Object $LOCK = new Object[0];

    private final Object $lock = new Object[0];

    private final Object readLock = new Object();

    

    public static void hello() {

        synchronized($LOCK) {

            System.out.println("world");

        }

    }

    

    public int answerToLife() {

        synchronized($lock) {

            return 42;

        }

    }

    

    public void foo() {

        synchronized(readLock) {

            System.out.println("bar");

        }

    }

}
Utils Cleanup

源代码:

import lombok.Cleanup;

import java.io.*;



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

        }

    }

}

编译之后:

import java.io.*;



public class CleanupExample {

    public static void main(String[] args) throws IOException {

        InputStream in = new FileInputStream(args[0]);

        try {

            OutputStream out = new FileOutputStream(args[1]);

            try {

                byte[] b = new byte[10000];

                while (true) {

                    int r = in.read(b);

                    if (r == -1) break;

                    out.write(b, 0, r);

                }

            } finally {

                if (out != null) {

                    out.close();

                }

            }

        } finally {

            if (in != null) {

                in.close();

            }

        }

    }

}
Log:日志

使用@Log或者类似注解可以为类自动创建一个log对象,其效果如下所示:

@CommonsLog

Creates private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);

@Log

Creates private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());

@Log4j

Creates private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);

@Log4j2

Creates private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);

@Slf4j

Creates private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

@XSlf4j

Creates private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

使用了Lombok之后的代码如下:

import lombok.extern.java.Log;

import lombok.extern.slf4j.Slf4j;



@Log

public class LogExample {

    

    public static void main(String... args) {

        log.error("Something"s wrong here");

    }

}



@Slf4j

public class LogExampleOther {

    

    public static void main(String... args) {

        log.error("Something else is wrong here");

    }

}



@CommonsLog(topic="CounterLog")

public class LogExampleCategory {



    public static void main(String... args) {

        log.error("Calling the "CounterLog" with a message");

    }

}

编译之后的代码如下:

public class LogExample {

    private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());

    

    public static void main(String... args) {

        log.error("Something"s wrong here");

    }

}



public class LogExampleOther {

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class);

    

    public static void main(String... args) {

        log.error("Something else is wrong here");

    }

}



public class LogExampleCategory {

    private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("CounterLog");



    public static void main(String... args) {

        log.error("Calling the "CounterLog" with a message");

    }

}

其他可配置的参数为:

lombok.log.fieldName = an identifier (default: log)

The generated logger fieldname is by default "log", but you can change it to a different name with this setting.

lombok.log.fieldIsStatic = [true | false] (default: true)

Normally the generated logger is a static field. By setting this key to false, the generated field will be an instance field instead.

lombok.log.flagUsage = [warning | error] (default: not set)

Lombok will flag any usage of any of the various log annotations as a warning or error if configured.

lombok.log.apacheCommons.flagUsage = [warning | error] (default: not set)

Lombok will flag any usage of @lombok.extern.apachecommons.CommonsLog as a warning or error if configured.

lombok.log.javaUtilLogging.flagUsage = [warning | error] (default: not set)

Lombok will flag any usage of @lombok.extern.java.Log as a warning or error if configured.

lombok.log.log4j.flagUsage = [warning | error] (default: not set)

Lombok will flag any usage of @lombok.extern.log4j.Log4j as a warning or error if configured.

lombok.log.log4j2.flagUsage = [warning | error] (default: not set)

Lombok will flag any usage of @lombok.extern.log4j.Log4j2 as a warning or error if configured.

lombok.log.slf4j.flagUsage = [warning | error] (default: not set)

Lombok will flag any usage of @lombok.extern.slf4j.Slf4j as a warning or error if configured.

lombok.log.xslf4j.flagUsage = [warning | error] (default: not set)

Lombok will flag any usage of @lombok.extern.slf4j.XSlf4j as a warning or error if configured.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65956.html

相关文章

  • Lombok介绍、使用方法和总结

    摘要:使用方法能以简单的注解形式来简化代码,提高开发人员的开发效率。能通过注解的方式,在编译时自动为属性生成构造器方法。出现的神奇就是在源码中没有和方法,但是在编译生成的字节码文件中有和方法。没法实现多种参数构造器的重载。 1 Lombok背景介绍 官方介绍如下: Project Lombok makes java a spicier language by addi...

    30e8336b8229 评论0 收藏0
  • 使用神器Lombok优雅编码

    摘要:提高编码效率使代码更简洁消除冗长代码避免修改字段名字时忘记修改方法名提高下逼格以上就是的优点,当然,的优点远远不止以上几点,使用,你可以更加优雅高效的编辑代码。实战完成了上述准备之后,就可以愉快的使用进行编码了。接下来是使用简化后的代码。 Lombok介绍 近来偶遇一款撸码神器,介绍给大家~相信许多小伙伴都深有体会,POJO类中的千篇一律的getter/setter,construct...

    _ang 评论0 收藏0
  • java第三方包学习之lombok

    摘要:不久前发现有一个第三方库可以在一定程度上帮助我们从体力劳动中解救出来,它就是。来看自动生成的方法中对于数组采用的是。检查传入对象是否为,若为,则抛出异常。比如自动抛受检异常,而无需显式在方法上使用语句。 前言 Laziness is a virtue!每当写pojo类时,都会重复写一些setter/getter/toString方法等大量的模版代码,无聊繁琐却又不得不做,这会让这个类变...

    GitCafe 评论0 收藏0
  • lombok使用

    摘要:虽然有人可能会说里面都自带自动生成这些方法的功能,但是使用会使你的代码看起来更加简洁,写起来也更加方便。使用不使用自动生成方法使用不使用自动生成无参数构造函数。 一、lombok简介 lombok是在学习过程中发现的一个非常好用的小工具,用了之后感觉的确很不错,所以特此来推荐一下。 lombok的官方地址:https://projectlombok.org/ lombok的Github...

    MobService 评论0 收藏0
  • lombok基本注解使用

    摘要:是一款在开发中简洁化代码十分有用的插件工具,使用注解,目的和作用就在于不用再去写经常反复去写的如,,等一些机械性代码了。也可以设置不包含哪些字段使用这个注解,就不用再去手写等方法了,注解后在编译时会自动加进去。 lombok是一款在java开发中简洁化代码十分有用的插件工具,使用lombok注解,目的和作用就在于不用再去写经常反复去写的(如Getter,Setter,Construct...

    AaronYuan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<