Skip to content

@Getter(lazy=true)

YellowStar5 edited this page Aug 2, 2019 · 1 revision

@Getter(lazy=true)

Laziness(惰性加载)是一种美德!

@Getter(lazy=true) 是在 Lombok v0.10 中引入的。

概览

你可以让 lombok 生成一个 getter,第一次调用这个 getter 方法的时候会计算一次值,并从这之后缓存它。 如果计算该值占用大量 CPU,或者该值占用大量内存,则此功能非常有用。 要使用此功能,请创建一个 private final 变量,使用运行成本高的表达式对其进行初始化,并使用 @Getter(lazy=true) 注释你的字段。 该字段将从代码的其余部分隐藏,并且当首次调用 getter 时,表达式将被执行不超过一次。 没有魔术标记值(即使你的昂贵计算的结果为 null,结果也会被缓存)并且昂贵的计算不需要是线程安全的,因为 lombok 负责锁定。

如果初始化表达式很复杂或包含泛型,我们建议将代码移动到私有(如果可能的话用静态)方法,并调用它。

With Lombok

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

Vanilla Java

public class GetterLazyExample {
  private final java.util.concurrent.AtomicReference<java.lang.Object> cached = new java.util.concurrent.AtomicReference<java.lang.Object>();
  
  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;
  }
}

支持的配置键

lombok.getter.lazy.flagUsage = [ warning | error ](默认:未设置)

如果已配置,Lombok会将 @Getter(lazy=true) 的任何用法标记为警告或错误。

Small Print

你永远不应该直接引用该字段,总是使用lombok生成的getter,因为该字段的类型将被添加到 AtomicReference 中。 不要试图直接访问此 AtomicReference; 如果它指向自身,则已经计算过该值,并且它为 null。 如果引用指向 null,则表示尚未计算该值。 此行为可能会在将来的版本中更改。 因此,始终使用生成的 getter 访问你的字段!

即使你使用 doNotUseGetters=true ,其他 Lombok 注释(如 @ToString )也始终调用 getter。

Clone this wiki locally