Lazy { @SuppressWarnings("unchecked") public T getOrCompute(@Nonnull Supplier<T> supplier) { final Object v1 = value; if (v1 == LAZY_NULL) { return null; } else { if (v1 == null) { Object v2 = maybeCompute(supplier); return v2 == LAZY_NULL ? null : (T) v2; } else { return (T) v1; } } }  @SuppressWarnings("unchecked") T getOrCompute(@Nonnull Supplier<T> supplier); synchronized void reset();  }
@Test public void lazyRetainsNonNullValue() { Lazy<Object> lazy = new Lazy<>(); Object instance = new Object(); Object o1 = lazy.getOrCompute(() -> instance); assertEquals(o1, instance); Object o2 = lazy.getOrCompute(() -> instance); assertEquals(o2, instance); }
@Test public void lazyRetainsNullValue() { Lazy<Object> lazy = new Lazy<>(); Object o1 = lazy.getOrCompute(() -> null); assertNull(o1); }
@Test public void lazyOnlyComputesOnce() { Lazy<Object> lazy = new Lazy<>(); final Object instance = new Object(); Supplier<Object> supplier = new Supplier<Object>() { final AtomicInteger count = new AtomicInteger(0); @Override public Object get() { if (count.incrementAndGet() != 1) { throw new IllegalStateException(); } else { return instance; } } }; Object o1 = lazy.getOrCompute(supplier); assertEquals(o1, instance); Object o2 = lazy.getOrCompute(supplier); assertEquals(o2, instance); }