Lombok之@Getter(lazy = true)使用

一. 为什么要用?

现在需要对一个成员变量初始化,单初始化很复杂需要一个初始化函数。要怎么做呢。一直方法public 暴露这个初始方法,对象调用,然后然后在赋值给成员变量。这样的带来的后果就是,这个复杂切耗费资源方法可能被外部多次调用。优化可以给成private ,然后调用get 方法,然后由get 方法调用,初始化方法。这时候又要考虑线程安全问题,初始化方法没跑完,多线程又调用初始化方法。而获得null 值。如何保证初始化方法只执行一次,并且在多线程下是线程安全的。这个注解应该也可以用在创建单例模式。如果上面这些自己实现的话,需要写很多代码,但有了lombok,一个注解就够了。

AtomicReference 产考
Java并发编程——AtomicReference,解决并发修改多个属性(转)

二. 如何使用?

申明final的成员变量,复查切耗时的expensive()

class Test {

    private String name;
    @Getter(lazy = true)
    private  final double[] cached = expensive();
    private String age;

    Test(String name, String password, String age) {
        this.name = name;
        this.age = age;
    }


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

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

反编译后的代码如下: 发现了没,和单例懒汉模型,双检查锁机制是不是很像啊

class Test {
    private String name;
    private final AtomicReference<Object> cached = new AtomicReference();
    private String age;

    Test(String name, String password, String age) {
        this.name = name;
        this.age = age;
    }

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

    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[])(value == this.cached ? null : value);
    }
}

三. 源码

@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Getter {
    AccessLevel value() default AccessLevel.PUBLIC;

    Getter.AnyAnnotation[] onMethod() default {};

    boolean lazy() default false;

    /** @deprecated */
    @Deprecated
    @Retention(RetentionPolicy.SOURCE)
    @Target({})
    public @interface AnyAnnotation {
    }
}

四. 特别说明

本文已经收录在Lombok注解系列文章总览中,并继承上文中所提的特别说明

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。