Lombok 依赖和插件介绍-3

2021-09-25 0 By admin

接上文,继续介绍 Lombok 注解:

Lombok 依赖和插件介绍-2

二、Lombok 注解介绍

2.11、@SneakyThrows 抛出和捕获异常

还在手动捕获并抛出异常?使用@SneakyThrows注解自动实现试试!

public class SneakyThrowsExample {
    //自动抛出异常,无需处理
    @SneakyThrows(UnsupportedEncodingException.class)
    public static byte[] str2byte(String str){
        return str.getBytes("UTF-8");
    }

    public static void main(String[] args) {
        String str = "Hello World!";
        System.out.println(str2byte(str).length);
    }
}

编译后Lombok会生成如下代码。

public class SneakyThrowsExample {
    public SneakyThrowsExample() {
    }

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

2.12、@Synchronized 同步访问

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

@Data
public class SynchronizedExample {
    @NonNull
    private Integer count;

    @Synchronized
    @SneakyThrows
    public void reduceCount(Integer id) {
        if (count > 0) {
            Thread.sleep(500);
            count--;
            System.out.println(String.format("thread-%d count:%d", id, count));
        }
    }

    public static void main(String[] args) {
        //添加@Synchronized三个线程可以同步调用reduceCount方法
        SynchronizedExample example = new SynchronizedExample(20);
        new ReduceThread(1, example).start();
        new ReduceThread(2, example).start();
        new ReduceThread(3, example).start();
    }


    @RequiredArgsConstructor
    static class ReduceThread extends Thread {
        @NonNull
        private Integer id;
        @NonNull
        private SynchronizedExample example;

        @Override
        public void run() {
            while (example.getCount() > 0) {
                example.reduceCount(id);
            }
        }
    }
}

编译后Lombok会生成如下代码。

public class SynchronizedExample {
    private final Object $lock = new Object[0];
    @NonNull
    private Integer count;

    public void reduceCount(Integer id) {
        try {
            synchronized(this.$lock) {
                if (this.count > 0) {
                    Thread.sleep(500L);
                    Integer var3 = this.count;
                    Integer var4 = this.count = this.count - 1;
                    System.out.println(String.format("thread-%d count:%d", id, this.count));
                }

            }
        } catch (Throwable var7) {
            throw var7;
        }
    }
}

2.13、@With 对象克隆

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

@With
@AllArgsConstructor
public class WithExample {
    private Long id;
    private String name;
    private Integer age;

    public static void main(String[] args) {
        WithExample example1 = new WithExample(1L, "test", 20);
        WithExample example2 = example1.withAge(22);
        //将原对象进行clone并设置age,返回false
        System.out.println(example1.equals(example2));
    }
}

编译后Lombok会生成如下代码。

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

    public WithExample withId(final Long id) {
        return this.id == id ? this : new WithExample(id, this.name, this.age);
    }

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

    public WithExample withAge(final Integer age) {
        return this.age == age ? this : new WithExample(this.id, this.name, age);
    }

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

2.14、@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);
    }
}

编译后Lombok会生成如下代码。

public class GetterLazyExample {
    private final AtomicReference<Object> cached = new AtomicReference();

    public GetterLazyExample() {
    }

    private double[] expensive() {
        double[] result = new double[1000000];

        for(int i = 0; i < result.length; ++i) {
            result[i] = Math.asin((double)i);
        }

        return result;
    }

    public double[] getCached() {
        Object value = this.cached.get();
        if (value == null) {
            synchronized(this.cached) {
                value = this.cached.get();
                if (value == null) {
                    double[] actualValue = this.expensive();
                    value = actualValue == null ? this.cached : actualValue;
                    this.cached.set(value);
                }
            }
        }

        return (double[])((double[])(value == this.cached ? null : value));
    }
}

2.15、@Log 日志

使用@Log注解,可以直接生成日志对象log,通过log对象可以直接打印日志。

@Log
public class LogExample {
    public static void main(String[] args) {
        log.info("level info");
        log.warning("level warning");
        log.severe("level severe");
    }
}

编译后Lombok会生成如下代码。

public class LogExample {
    private static final Logger log = Logger.getLogger(LogExample.class.getName());

    public LogExample() {
    }

    public static void main(String[] args) {
        log.info("level info");
        log.warning("level warning");
        log.severe("level severe");
    }
}

2.16、@Slf4j 日志对象

使用Lombok生成日志对象时,根据使用日志实现的不同,有多种注解可以使用。比如@Log、@Log4j、@Log4j2、@Slf4j等。

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

编译后Lombok会生成如下代码。

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