1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2012 The Dagger Authors. 3*f585d8a3SJacky Wang * 4*f585d8a3SJacky Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5*f585d8a3SJacky Wang * you may not use this file except in compliance with the License. 6*f585d8a3SJacky Wang * You may obtain a copy of the License at 7*f585d8a3SJacky Wang * 8*f585d8a3SJacky Wang * http://www.apache.org/licenses/LICENSE-2.0 9*f585d8a3SJacky Wang * 10*f585d8a3SJacky Wang * Unless required by applicable law or agreed to in writing, software 11*f585d8a3SJacky Wang * distributed under the License is distributed on an "AS IS" BASIS, 12*f585d8a3SJacky Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*f585d8a3SJacky Wang * See the License for the specific language governing permissions and 14*f585d8a3SJacky Wang * limitations under the License. 15*f585d8a3SJacky Wang */ 16*f585d8a3SJacky Wang 17*f585d8a3SJacky Wang package dagger; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang /** 20*f585d8a3SJacky Wang * A handle to a lazily-computed value. Each {@code Lazy} computes its value on 21*f585d8a3SJacky Wang * the first call to {@link #get()} and remembers that same value for all 22*f585d8a3SJacky Wang * subsequent calls to {@code get()}. 23*f585d8a3SJacky Wang * 24*f585d8a3SJacky Wang * <p>All implementations are expected to be thread-safe and compute their value at most once. 25*f585d8a3SJacky Wang * 26*f585d8a3SJacky Wang * <h2>Example</h2> 27*f585d8a3SJacky Wang * The differences between <strong>direct injection</strong>, <strong>provider 28*f585d8a3SJacky Wang * injection</strong> and <strong>lazy injection</strong> are best demonstrated 29*f585d8a3SJacky Wang * with an example. Start with a module that computes a different integer for 30*f585d8a3SJacky Wang * each use:<pre><code> 31*f585d8a3SJacky Wang * {@literal @Module} 32*f585d8a3SJacky Wang * final class CounterModule { 33*f585d8a3SJacky Wang * int next = 100; 34*f585d8a3SJacky Wang * 35*f585d8a3SJacky Wang * {@literal @Provides} Integer provideInteger() { 36*f585d8a3SJacky Wang * System.out.println("computing..."); 37*f585d8a3SJacky Wang * return next++; 38*f585d8a3SJacky Wang * } 39*f585d8a3SJacky Wang * } 40*f585d8a3SJacky Wang * </code></pre> 41*f585d8a3SJacky Wang * 42*f585d8a3SJacky Wang * <h3>Direct Injection</h3> 43*f585d8a3SJacky Wang * This class injects that integer and prints it 3 times:<pre><code> 44*f585d8a3SJacky Wang * final class DirectCounter { 45*f585d8a3SJacky Wang * {@literal @Inject} Integer value; 46*f585d8a3SJacky Wang * 47*f585d8a3SJacky Wang * void print() { 48*f585d8a3SJacky Wang * System.out.println("printing..."); 49*f585d8a3SJacky Wang * System.out.println(value); 50*f585d8a3SJacky Wang * System.out.println(value); 51*f585d8a3SJacky Wang * System.out.println(value); 52*f585d8a3SJacky Wang * } 53*f585d8a3SJacky Wang * } 54*f585d8a3SJacky Wang * </code></pre> 55*f585d8a3SJacky Wang * Injecting a {@code DirectCounter} and invoking {@code print()} reveals that 56*f585d8a3SJacky Wang * the value is computed <i>before</i> it is required:<pre><code> 57*f585d8a3SJacky Wang * computing... 58*f585d8a3SJacky Wang * printing... 59*f585d8a3SJacky Wang * 100 60*f585d8a3SJacky Wang * 100 61*f585d8a3SJacky Wang * 100 62*f585d8a3SJacky Wang * </code></pre> 63*f585d8a3SJacky Wang * 64*f585d8a3SJacky Wang * <h3>Provider Injection</h3> 65*f585d8a3SJacky Wang * This class injects a {@linkplain javax.inject.Provider provider} for the 66*f585d8a3SJacky Wang * integer. It calls {@code Provider.get()} 3 times and prints each result: 67*f585d8a3SJacky Wang * <pre><code> 68*f585d8a3SJacky Wang * final class ProviderCounter { 69*f585d8a3SJacky Wang * {@literal @Inject Provider<Integer> provider;} 70*f585d8a3SJacky Wang * 71*f585d8a3SJacky Wang * void print() { 72*f585d8a3SJacky Wang * System.out.println("printing..."); 73*f585d8a3SJacky Wang * System.out.println(provider.get()); 74*f585d8a3SJacky Wang * System.out.println(provider.get()); 75*f585d8a3SJacky Wang * System.out.println(provider.get()); 76*f585d8a3SJacky Wang * } 77*f585d8a3SJacky Wang * } 78*f585d8a3SJacky Wang * </code></pre> 79*f585d8a3SJacky Wang * Injecting a {@code ProviderCounter} and invoking {@code print()} shows that 80*f585d8a3SJacky Wang * a new value is computed each time {@code Provider.get()} is used:<pre><code> 81*f585d8a3SJacky Wang * printing... 82*f585d8a3SJacky Wang * computing... 83*f585d8a3SJacky Wang * 100 84*f585d8a3SJacky Wang * computing... 85*f585d8a3SJacky Wang * 101 86*f585d8a3SJacky Wang * computing... 87*f585d8a3SJacky Wang * 102 88*f585d8a3SJacky Wang * </code></pre> 89*f585d8a3SJacky Wang * 90*f585d8a3SJacky Wang * <h3>Lazy Injection</h3> 91*f585d8a3SJacky Wang * This class injects a {@code Lazy} for the integer. Like the provider above, 92*f585d8a3SJacky Wang * it calls {@code Lazy.get()} 3 times and prints each result:<pre><code> 93*f585d8a3SJacky Wang * final class LazyCounter { 94*f585d8a3SJacky Wang * {@literal @Inject Lazy<Integer> lazy;} 95*f585d8a3SJacky Wang * 96*f585d8a3SJacky Wang * void print() { 97*f585d8a3SJacky Wang * System.out.println("printing..."); 98*f585d8a3SJacky Wang * System.out.println(lazy.get()); 99*f585d8a3SJacky Wang * System.out.println(lazy.get()); 100*f585d8a3SJacky Wang * System.out.println(lazy.get()); 101*f585d8a3SJacky Wang * } 102*f585d8a3SJacky Wang * } 103*f585d8a3SJacky Wang * </code></pre> 104*f585d8a3SJacky Wang * Injecting a {@code LazyCounter} and invoking {@code print()} shows that a new 105*f585d8a3SJacky Wang * value is computed immediately before it is needed. The same value is returned 106*f585d8a3SJacky Wang * for all subsequent uses:<pre><code> 107*f585d8a3SJacky Wang * printing... 108*f585d8a3SJacky Wang * computing... 109*f585d8a3SJacky Wang * 100 110*f585d8a3SJacky Wang * 100 111*f585d8a3SJacky Wang * 100 112*f585d8a3SJacky Wang * </code></pre> 113*f585d8a3SJacky Wang * 114*f585d8a3SJacky Wang * <h3>Lazy != Singleton</h3> 115*f585d8a3SJacky Wang * Note that each injected {@code Lazy} is independent, and remembers its value 116*f585d8a3SJacky Wang * in isolation of other {@code Lazy} instances. In this example, two {@code 117*f585d8a3SJacky Wang * LazyCounter} objects are created and {@code print()} is called on each: 118*f585d8a3SJacky Wang * <pre><code> 119*f585d8a3SJacky Wang * final class LazyCounters { 120*f585d8a3SJacky Wang * {@literal @Inject} LazyCounter counter1; 121*f585d8a3SJacky Wang * {@literal @Inject} LazyCounter counter2; 122*f585d8a3SJacky Wang * 123*f585d8a3SJacky Wang * void print() { 124*f585d8a3SJacky Wang * counter1.print(); 125*f585d8a3SJacky Wang * counter2.print(); 126*f585d8a3SJacky Wang * } 127*f585d8a3SJacky Wang * } 128*f585d8a3SJacky Wang * </code></pre> 129*f585d8a3SJacky Wang * The output demonstrates that each {@code Lazy} works independently: 130*f585d8a3SJacky Wang * <pre><code> 131*f585d8a3SJacky Wang * printing... 132*f585d8a3SJacky Wang * computing... 133*f585d8a3SJacky Wang * 100 134*f585d8a3SJacky Wang * 100 135*f585d8a3SJacky Wang * 100 136*f585d8a3SJacky Wang * printing... 137*f585d8a3SJacky Wang * computing... 138*f585d8a3SJacky Wang * 101 139*f585d8a3SJacky Wang * 101 140*f585d8a3SJacky Wang * 101 141*f585d8a3SJacky Wang * </code></pre> 142*f585d8a3SJacky Wang * Use {@link javax.inject.Singleton @Singleton} to share one instance among all 143*f585d8a3SJacky Wang * clients, and {@code Lazy} for lazy computation in a single client. 144*f585d8a3SJacky Wang */ 145*f585d8a3SJacky Wang public interface Lazy<T> { 146*f585d8a3SJacky Wang /** 147*f585d8a3SJacky Wang * Return the underlying value, computing the value if necessary. All calls to 148*f585d8a3SJacky Wang * the same {@code Lazy} instance will return the same result. 149*f585d8a3SJacky Wang */ get()150*f585d8a3SJacky Wang T get(); 151*f585d8a3SJacky Wang } 152