equal
deleted
inserted
replaced
36 * perform the message send quickly, for each class encountered. |
36 * perform the message send quickly, for each class encountered. |
37 * @author John Rose, JSR 292 EG |
37 * @author John Rose, JSR 292 EG |
38 * @since 1.7 |
38 * @since 1.7 |
39 */ |
39 */ |
40 public abstract class ClassValue<T> { |
40 public abstract class ClassValue<T> { |
|
41 /** |
|
42 * Sole constructor. (For invocation by subclass constructors, typically |
|
43 * implicit.) |
|
44 */ |
|
45 protected ClassValue() { |
|
46 } |
|
47 |
41 /** |
48 /** |
42 * Computes the given class's derived value for this {@code ClassValue}. |
49 * Computes the given class's derived value for this {@code ClassValue}. |
43 * <p> |
50 * <p> |
44 * This method will be invoked within the first thread that accesses |
51 * This method will be invoked within the first thread that accesses |
45 * the value with the {@link #get get} method. |
52 * the value with the {@link #get get} method. |
98 /** |
105 /** |
99 * Removes the associated value for the given class. |
106 * Removes the associated value for the given class. |
100 * If this value is subsequently {@linkplain #get read} for the same class, |
107 * If this value is subsequently {@linkplain #get read} for the same class, |
101 * its value will be reinitialized by invoking its {@link #computeValue computeValue} method. |
108 * its value will be reinitialized by invoking its {@link #computeValue computeValue} method. |
102 * This may result in an additional invocation of the |
109 * This may result in an additional invocation of the |
103 * {@code computeValue computeValue} method for the given class. |
110 * {@code computeValue} method for the given class. |
104 * <p> |
111 * <p> |
105 * In order to explain the interaction between {@code get} and {@code remove} calls, |
112 * In order to explain the interaction between {@code get} and {@code remove} calls, |
106 * we must model the state transitions of a class value to take into account |
113 * we must model the state transitions of a class value to take into account |
107 * the alternation between uninitialized and initialized states. |
114 * the alternation between uninitialized and initialized states. |
108 * To do this, number these states sequentially from zero, and note that |
115 * To do this, number these states sequentially from zero, and note that |
191 // Replace this map by a per-class slot. |
198 // Replace this map by a per-class slot. |
192 private static final WeakHashMap<Class<?>, ClassValueMap> ROOT |
199 private static final WeakHashMap<Class<?>, ClassValueMap> ROOT |
193 = new WeakHashMap<Class<?>, ClassValueMap>(); |
200 = new WeakHashMap<Class<?>, ClassValueMap>(); |
194 |
201 |
195 private static ClassValueMap getMap(Class<?> type) { |
202 private static ClassValueMap getMap(Class<?> type) { |
|
203 type.getClass(); // test for null |
196 return ROOT.get(type); |
204 return ROOT.get(type); |
197 } |
205 } |
198 |
206 |
199 private static ClassValueMap initializeMap(Class<?> type) { |
207 private static ClassValueMap initializeMap(Class<?> type) { |
200 synchronized (ClassValue.class) { |
208 synchronized (ClassValue.class) { |