Lombok还只会使用@Data???大材小用

简介

Lombok是一款Java代码功能增强库,它会自动集成到你的编辑器和构建工具中,从而使你的Java代码更加生动有趣。通过Lombok的注解,你可以不用再写getter、setter、equals等方法,Lombok将在编译时为你自动生成。

集成

首先我们需要在IDEA中安装好Lombok插件,如果你使用的是最新版IDEA 2020.3,则Lombok插件已经内置,无需安装。

maven依赖

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

用例一:@val

使用val注解可以取代任意类型作为局部变量

    @Test
    public void valExample() {
        // 1.使用@val注解可以取代任意类型作为局部变量
        val val = new ArrayList<String>(16);
        val.add("1");
        val.add("2");

        String s = val.get(1);
        System.out.println(s);
        System.out.println(val);
    }


用例二: @NonNull

在方法上使用@NonNull注解可以做非空判断,如果传入空值的话会直接抛出NullPointerException。

    @Test
    public void nonNullExample() {
        // 2.@NonNull的使用,直接会报空指针,原因是编译后的class会直接加上非空判断
        String name = null;
        notNullExample(name);
    }
    private static void notNullExample(@NonNull String name) {
        System.out.println(name);
    }

编译后的class

    @Test
    public void nonNullExample() {
        String name = null;
        notNullExample((String)name);
    }

    private static void notNullExample(@NonNull String name) {
        if (name == null) {
            throw new NullPointerException("name is marked non-null but is null");
        } else {
            System.out.println(name);
        }
    }

用例三:@Cleanup

当我们在Java中使用资源时,不可避免地需要在使用后关闭资源。使用@Cleanup注解可以自动关闭资源。

/**
 * @author liumf
 * 使用输入输出流自动关闭,无需编写try catch和调用close()方法
 * class 文件编译后会自动生成finally释放资源
 * @throws IOException
 */

@Test
public void CleanupExample() throws Exception {
    String inStr = "Hello World!";
    //使用输入输出流自动关闭,无需编写try catch和调用close()方法
    @Cleanup ByteArrayInputStream in = new ByteArrayInputStream(inStr.getBytes("UTF-8"));
    @Cleanup ByteArrayOutputStream out = new ByteArrayOutputStream();
    byte[] b = new byte[1024];
    while (true) {
        int r = in.read(b);
        if (r == -1) break;
        out.write(b, 0, r);
    }
    String outStr = out.toString("UTF-8");
    System.out.println(outStr);
}

编译后的class

   @Test
    public void CleanupExample() throws Exception {
        String inStr = "Hello World!";
        ByteArrayInputStream in = new ByteArrayInputStream(inStr.getBytes("UTF-8"));

        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            try {
                byte[] b = new byte[1024];

                while(true) {
                    int r = in.read(b);
                    if (r == -1) {
                        String outStr = out.toString("UTF-8");
                        System.out.println(outStr);
                        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();
            }

        }
    }

用例四:@Builder

使用@Builder注解可以通过建造者模式来创建对象,建造者模式加链式调用,创建对象太方便了!

    /**
     * 使用@Builder注解可以通过建造者模式来创建对象,建造者模式加链式调用,创建对象太方便了!
     * 注意最后要加上.build()
     */
    @Test
    public void buildExample(){
        User user = User.builder()
                .name("liu")
                .pwd("xy").build();
        notNullProperty(user);
    }
    private static void notNullProperty(@NonNull User user) {
        System.out.println(user);
    }


用例五:@SneakyThrows

给手动抛出异常sayNo

    /**
     * 手动抛出异常??????试试@SneakyThrows
     */
    @Test
    public void neakyThrowsExample() {
        String str = "Hello World!";
        System.out.println(str2byte(str).length);
    }
    //自动抛出异常,无需处理
    @SneakyThrows(UnsupportedEncodingException.class)
    public byte[] str2byte(String str) {
        return str.getBytes("UTF-8");
    }



编译后的class

    @Test
    public void neakyThrowsExample() {
        String str = "Hello World!";
        System.out.println(this.str2byte(str).length);
    }

    public byte[] str2byte(String str) {
        try {
            return str.getBytes("UTF-8");
        } catch (UnsupportedEncodingException var3) {
            throw var3;
        }
    }

用例六:@Synchronized

当我们在多个线程中访问同一资源时,往往会出现线程安全问题,以前我们往往使用synchronized关键字修饰方法来实现同步访问。使用@Synchronized注解同样可以实现同步访问。

    private static LombokExample lombokExample;
    private LombokExample() {
    }
    @Synchronized
    public static LombokExample getLombokExample(){
        // if (lombokExample == null){
            synchronized (LombokExample.class){
                if (lombokExample ==null){
                    lombokExample = new LombokExample();
                }
            }
        // }
        return lombokExample;
    }

编译后的class

 	private static LombokExample lombokExample;
    private LombokExample() {
    }

    public static LombokExample getLombokExample() {
        synchronized($LOCK) {
            Class var1 = LombokExample.class;
            synchronized(LombokExample.class) {
                if (lombokExample == null) {
                    lombokExample = new LombokExample();
                }
            }

            return lombokExample;
        }
    }


用例七:@With

使用@With注解可以实现对原对象进行克隆,并改变其一个属性,使用时需要指定全参构造方法。

    /**
     * @With注解
     * 实现对象clone
     * @Log4j 打印日志
     * @param args
     */
    public static void main(String[] args) {
        Student student1 = new Student("liu", "15");
        System.out.println(student1);
        Student student2 = student1.withAge("19");
        log.error("xxxxx");
        System.out.println(student2);
    }


用例八:@Getter(lazy=true)

当我们获取某一个属性比较消耗资源时,可以给@Getter添加lazy=true属性实现懒加载,会生成Double Check Lock 样板代码对属性进行懒加载。

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 static void main(String[] args) {
        //使用Double Check Lock 样板代码对属性进行懒加载
        GetterLazyExample example = new GetterLazyExample();
        System.out.println(example.getCached().length);
    }
}

用例九:@Log、@Log4j、@Log4j2、@Slf4


@Slf4j
public class LogSlf4jExample {
    public static void main(String[] args) {
        log.info("level:{}","info");
        log.warn("level:{}","warn");
        log.error("level:{}", "error");
    }
}


编译后的class


public class LogSlf4jExample {
    private static final Logger log = LoggerFactory.getLogger(LogSlf4jExample.class);

    public LogSlf4jExample() {
    }

    public static void main(String[] args) {
        log.info("level:{}", "info");
        log.warn("level:{}", "warn");
        log.error("level:{}", "error");
    }
}

用例十:@Value

使用@Value注解可以把类声明为不可变的,声明后此类相当于final类,无法被继承,其属性也会变成final属性。


package lombok.pojo;

import lombok.AllArgsConstructor;
import lombok.ToString;
import lombok.Value;
import lombok.With;
import lombok.extern.java.Log;
import lombok.extern.log4j.Log4j;
import org.junit.Test;

/**
 * @author liumf
 * @date 22:41 2020/12/23
 * @className Student
 * @description
 */
@AllArgsConstructor
@With
@ToString
@Log4j
@Value

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

    /**
     * @With注解
     * 实现对象clone
     * @Log4j 打印日志
     * @param args
     */
    public static void main(String[] args) {
        Student student1 = new Student("liu", "15");
        System.out.println(student1);
        Student student2 = student1.withAge("19");
        log.error("xxxxx");
        System.out.println(student2);
    }

}



编译后的class


public final class Student {
    private static final Logger log = Logger.getLogger(Student.class);
    private final String name;
    private final String age;

    public static void main(String[] args) {
        Student student1 = new Student("liu", "15");
        System.out.println(student1);
        Student student2 = student1.withAge("19");
        log.error("xxxxx");
        System.out.println(student2);
    }

用例十一:@Getter/@Setter @ToString @EqualsAndHashCode

  1. @Getter/@Setter注解,我们再也不用编写getter/setter方法了
  2. 使用@ToString注解可以自动生成toString方法,默认会包含所有类属性,使用@ToString.Exclude注解可以排除属性的生成。
  3. 使用@EqualsAndHashCode注解可以自动生成hashCode和equals方法,默认包含所有类属性,使用@EqualsAndHashCode.Exclude可以排除属性的生成。

/**
* @ToString 
*
*/

public class ToStringExample {
    private Long id;
    private String name;
    private Integer age;

    public ToStringExample(Long id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String toString() {
        return "ToStringExample(name=" + this.name + ", age=" + this.age + ")";
    }
}


/**
* @EqualsAndHashCode
*
*/

@Getter
@Setter
@EqualsAndHashCode
public class EqualsAndHashCodeExample {
    private Long id;
    @EqualsAndHashCode.Exclude
    private String name;
    @EqualsAndHashCode.Exclude
    private Integer age;

    public static void main(String[] args) {
        EqualsAndHashCodeExample example1 = new EqualsAndHashCodeExample();
        example1.setId(1L);
        example1.setName("test");
        example1.setAge(20);
        EqualsAndHashCodeExample example2 = new EqualsAndHashCodeExample();
        example2.setId(1L);
        //equals方法只对比id,返回true
        System.out.println(example1.equals(example2));
    }
}

编译后的class

public class User {
    private String name;
    private String pwd;

    public static void main(String[] args) {
        LombokExample lombokExample = LombokExample.getLombokExample();
        System.out.println(lombokExample);
    }

    public static User.UserBuilder builder() {
        return new User.UserBuilder();
    }

    public User withName(String name) {
        return this.name == name ? this : new User(name, this.pwd);
    }

    public User withPwd(String pwd) {
        return this.pwd == pwd ? this : new User(this.name, pwd);
    }

    public String getName() {
        return this.name;
    }

    public String getPwd() {
        return this.pwd;
    }

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

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof User)) {
            return false;
        } else {
            User other = (User)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                Object this$name = this.getName();
                Object other$name = other.getName();
                if (this$name == null) {
                    if (other$name != null) {
                        return false;
                    }
                } else if (!this$name.equals(other$name)) {
                    return false;
                }

                Object this$pwd = this.getPwd();
                Object other$pwd = other.getPwd();
                if (this$pwd == null) {
                    if (other$pwd != null) {
                        return false;
                    }
                } else if (!this$pwd.equals(other$pwd)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof User;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $name = this.getName();
        int result = result * 59 + ($name == null ? 43 : $name.hashCode());
        Object $pwd = this.getPwd();
        result = result * 59 + ($pwd == null ? 43 : $pwd.hashCode());
        return result;
    }

    public String toString() {
        return "User(name=" + this.getName() + ", pwd=" + this.getPwd() + ")";
    }

    public User(String name, String pwd) {
        this.name = name;
        this.pwd = pwd;
    }

    public static class UserBuilder {
        private String name;
        private String pwd;

        UserBuilder() {
        }

        public User.UserBuilder name(String name) {
            this.name = name;
            return this;
        }

        public User.UserBuilder pwd(String pwd) {
            this.pwd = pwd;
            return this;
        }

        public User build() {
            return new User(this.name, this.pwd);
        }

        public String toString() {
            return "User.UserBuilder(name=" + this.name + ", pwd=" + this.pwd + ")";
        }
    }
}

用例十一:@XxConstructor

使用@XxConstructor注解可以自动生成构造方法,有@NoArgsConstructor、@RequiredArgsConstructor和@AllArgsConstructor三个注解可以使用。

  • @NoArgsConstructor:生成无参构造函数。
  • @RequiredArgsConstructor:生成包含必须参数的构造函数,使用@NonNull注解的类属性为必须参数
  • @AllArgsConstructor:生成包含所有参数的构造函数
@NoArgsConstructor
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor
public class ConstructorExample {
    @NonNull
    private Long id;
    private String name;
    private Integer age;

    public static void main(String[] args) {
        //无参构造器
        ConstructorExample example1 = new ConstructorExample();
        //全部参数构造器
        ConstructorExample example2 = new ConstructorExample(1L,"test",20);
        //@NonNull注解的必须参数构造器
        ConstructorExample example3 = ConstructorExample.of(1L);
    }
}

编译后的class

public class ConstructorExample {
    @NonNull
    private Long id;
    private String name;
    private Integer age;

    public ConstructorExample() {
    }

    private ConstructorExample(@NonNull final Long id) {
        if (id == null) {
            throw new NullPointerException("id is marked non-null but is null");
        } else {
            this.id = id;
        }
    }

    public static ConstructorExample of(@NonNull final Long id) {
        return new ConstructorExample(id);
    }

    public ConstructorExample(@NonNull final Long id, final String name, final Integer age) {
        if (id == null) {
            throw new NullPointerException("id is marked non-null but is null");
        } else {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    }
}

用例十一:@Data

@Data是一个方便使用的组合注解,是@ToString、@EqualsAndHashCode、@Getter、@Setter和@RequiredArgsConstructor的组合体。

编译后

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package lombok.pojo;

import org.apache.log4j.Logger;

public final class Student {
    private static final Logger log = Logger.getLogger(Student.class);
    private final String name;
    private final String age;

    public static void main(String[] args) {
        Student student1 = new Student("liu", "15");
        System.out.println(student1);
        Student student2 = student1.withAge("19");
        log.error("xxxxx");
        System.out.println(student2);
    }

    public String getName() {
        return this.name;
    }

    public String getAge() {
        return this.age;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Student)) {
            return false;
        } else {
            Student other = (Student)o;
            Object this$name = this.getName();
            Object other$name = other.getName();
            if (this$name == null) {
                if (other$name != null) {
                    return false;
                }
            } else if (!this$name.equals(other$name)) {
                return false;
            }

            Object this$age = this.getAge();
            Object other$age = other.getAge();
            if (this$age == null) {
                if (other$age != null) {
                    return false;
                }
            } else if (!this$age.equals(other$age)) {
                return false;
            }

            return true;
        }
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $name = this.getName();
        int result = result * 59 + ($name == null ? 43 : $name.hashCode());
        Object $age = this.getAge();
        result = result * 59 + ($age == null ? 43 : $age.hashCode());
        return result;
    }

    public Student(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public Student withName(String name) {
        return this.name == name ? this : new Student(name, this.age);
    }

    public Student withAge(String age) {
        return this.age == age ? this : new Student(this.name, age);
    }

    public String toString() {
        return "Student(name=" + this.getName() + ", age=" + this.getAge() + ")";
    }
}

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值