1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ****************************************************************************** 5 * Copyright (C) 2005-2016, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ****************************************************************************** 8 */ 9 package com.ibm.icu.util; 10 11 /** 12 * Provides a flexible mechanism for controlling access, without requiring that 13 * a class be immutable. Once frozen, an object can never be unfrozen, so it is 14 * thread-safe from that point onward. Once the object has been frozen, 15 * it must guarantee that no changes can be made to it. Any attempt to alter 16 * it must raise an UnsupportedOperationException exception. This means that when 17 * the object returns internal objects, or if anyone has references to those internal 18 * objects, that those internal objects must either be immutable, or must also 19 * raise exceptions if any attempt to modify them is made. Of course, the object 20 * can return clones of internal objects, since those are safe. 21 * <h2>Background</h2> 22 * <p> 23 * There are often times when you need objects to be objects 'safe', so that 24 * they can't be modified. Examples are when objects need to be thread-safe, or 25 * in writing robust code, or in caches. If you are only creating your own 26 * objects, you can guarantee this, of course -- but only if you don't make a 27 * mistake. If you have objects handed into you, or are creating objects using 28 * others handed into you, it is a different story. It all comes down to whether 29 * you want to take the Blanche Dubois approach ("depend on the kindness of 30 * strangers") or the Andy Grove approach ("Only the Paranoid 31 * Survive"). 32 * </p> 33 * <p> 34 * For example, suppose we have a simple class: 35 * </p> 36 * 37 * <pre> 38 * public class A { 39 * protected Collection b; 40 * 41 * protected Collection c; 42 * 43 * public Collection get_b() { 44 * return b; 45 * } 46 * 47 * public Collection get_c() { 48 * return c; 49 * } 50 * 51 * public A(Collection new_b, Collection new_c) { 52 * b = new_b; 53 * c = new_c; 54 * } 55 * } 56 * </pre> 57 * 58 * <p> 59 * Since the class doesn't have any setters, someone might think that it is 60 * immutable. You know where this is leading, of course; this class is unsafe in 61 * a number of ways. The following illustrates that. 62 * </p> 63 * 64 * <pre> 65 * public test1(SupposedlyImmutableClass x, SafeStorage y) { 66 * // unsafe getter 67 * A a = x.getA(); 68 * Collection col = a.get_b(); 69 * col.add(something); // a has now been changed, and x too 70 * 71 * // unsafe constructor 72 * a = new A(col, col); 73 * y.store(a); 74 * col.add(something); // a has now been changed, and y too 75 * } 76 * </pre> 77 * 78 * <p> 79 * There are a few different techniques for having safe classes. 80 * </p> 81 * <ol> 82 * <li>Const objects. In C++, you can declare parameters const.</li> 83 * <li>Immutable wrappers. For example, you can put a collection in an 84 * immutable wrapper.</li> 85 * <li>Always-Immutable objects. Java uses this approach, with a few 86 * variations. Examples: 87 * <ol> 88 * <li>Simple. Once a Color is created (eg from R, G, and B integers) it is 89 * immutable.</li> 90 * <li>Builder Class. There is a separate 'builder' class. For example, 91 * modifiable Strings are created using StringBuffer (which doesn't have the 92 * full String API available). Once you want an immutable form, you create one 93 * with toString().</li> 94 * <li>Primitives. These are always safe, since they are copied on input/output 95 * from methods.</li> 96 * </ol> 97 * </li> 98 * <li>Cloning. Where you need an object to be safe, you clone it.</li> 99 * </ol> 100 * <p> 101 * There are advantages and disadvantages of each of these. 102 * </p> 103 * <ol> 104 * <li>Const provides a certain level of protection, but since const can be and 105 * is often cast away, it only protects against most inadvertent mistakes. It 106 * also offers no threading protection, since anyone who has a pointer to the 107 * (unconst) object in another thread can mess you up.</li> 108 * <li>Immutable wrappers are safer than const in that the constness can't be 109 * cast away. But other than that they have all the same problems: not safe if 110 * someone else keeps hold of the original object, or if any of the objects 111 * returned by the class are mutable.</li> 112 * <li>Always-Immutable Objects are safe, but usage can require excessive 113 * object creation.</li> 114 * <li>Cloning is only safe if the object truly has a 'safe' clone; defined as 115 * one that <i>ensures that no change to the clone affects the original</i>. 116 * Unfortunately, many objects don't have a 'safe' clone, and always cloning can 117 * require excessive object creation.</li> 118 * </ol> 119 * <h2>Freezable Model</h2> 120 * <p> 121 * The <code>Freezable</code> model supplements these choices by giving you 122 * the ability to build up an object by calling various methods, then when it is 123 * in a final state, you can <i>make</i> it immutable. Once immutable, an 124 * object cannot <i>ever </i>be modified, and is completely thread-safe: that 125 * is, multiple threads can have references to it without any synchronization. 126 * If someone needs a mutable version of an object, they can use 127 * <code>cloneAsThawed()</code>, and modify the copy. This provides a simple, 128 * effective mechanism for safe classes in circumstances where the alternatives 129 * are insufficient or clumsy. (If an object is shared before it is immutable, 130 * then it is the responsibility of each thread to mutex its usage (as with 131 * other objects).) 132 * </p> 133 * <p> 134 * Here is what needs to be done to implement this interface, depending on the 135 * type of the object. 136 * </p> 137 * <h3><b>Immutable Objects</b></h3> 138 * <p> 139 * These are the easiest. You just use the interface to reflect that, by adding 140 * the following: 141 * </p> 142 * 143 * <pre> 144 * public class A implements Freezable<A> { 145 * ... 146 * public final boolean isFrozen() {return true;} 147 * public final A freeze() {return this;} 148 * public final A cloneAsThawed() { return this; } 149 * } 150 * </pre> 151 * 152 * <p> 153 * These can be final methods because subclasses of immutable objects must 154 * themselves be immutable. (Note: <code>freeze</code> is returning 155 * <code>this</code> for chaining.) 156 * </p> 157 * <h3><b>Mutable Objects</b></h3> 158 * <p> 159 * Add a protected 'flagging' field: 160 * </p> 161 * 162 * <pre> 163 * protected volatile boolean frozen; // WARNING: must be volatile 164 * </pre> 165 * 166 * <p> 167 * Add the following methods: 168 * </p> 169 * 170 * <pre> 171 * public final boolean isFrozen() { 172 * return frozen; 173 * }; 174 * 175 * public A freeze() { 176 * frozen = true; // WARNING: must be final statement before return 177 * return this; 178 * } 179 * </pre> 180 * 181 * <p> 182 * Add a <code>cloneAsThawed()</code> method following the normal pattern for 183 * <code>clone()</code>, except that <code>frozen=false</code> in the new 184 * clone. 185 * </p> 186 * <p> 187 * Then take the setters (that is, any method that can change the internal state 188 * of the object), and add the following as the first statement: 189 * </p> 190 * 191 * <pre> 192 * if (isFrozen()) { 193 * throw new UnsupportedOperationException("Attempt to modify frozen object"); 194 * } 195 * </pre> 196 * 197 * <h4><b>Subclassing</b></h4> 198 * <p> 199 * Any subclass of a <code>Freezable</code> will just use its superclass's 200 * flagging field. It must override <code>freeze()</code> and 201 * <code>cloneAsThawed()</code> to call the superclass, but normally does not 202 * override <code>isFrozen()</code>. It must then just pay attention to its 203 * own getters, setters and fields. 204 * </p> 205 * <h4><b>Internal Caches</b></h4> 206 * <p> 207 * Internal caches are cases where the object is logically unmodified, but 208 * internal state of the object changes. For example, there are const C++ 209 * functions that cast away the const on the "this" pointer in order 210 * to modify an object cache. These cases are handled by mutexing the internal 211 * cache to ensure thread-safety. For example, suppose that UnicodeSet had an 212 * internal marker to the last code point accessed. In this case, the field is 213 * not externally visible, so the only thing you need to do is to synchronize 214 * the field for thread safety. 215 * </p> 216 * <h4>Unsafe Internal Access</h4> 217 * <p> 218 * Internal fields are called <i>safe</i> if they are either 219 * <code>frozen</code> or immutable (such as String or primitives). If you've 220 * never allowed internal access to these, then you are all done. For example, 221 * converting UnicodeSet to be <code>Freezable</code> is just accomplished 222 * with the above steps. But remember that you <i><b>have</b></i> allowed 223 * access to unsafe internals if you have any code like the following, in a 224 * getter, setter, or constructor: 225 * </p> 226 * 227 * <pre> 228 * Collection getStuff() { 229 * return stuff; 230 * } // caller could keep reference & modify 231 * 232 * void setStuff(Collection x) { 233 * stuff = x; 234 * } // caller could keep reference & modify 235 * 236 * MyClass(Collection x) { 237 * stuff = x; 238 * } // caller could keep reference & modify 239 * </pre> 240 * 241 * <p> 242 * These also illustrated in the code sample in <b>Background</b> above. 243 * </p> 244 * <p> 245 * To deal with unsafe internals, the simplest course of action is to do the 246 * work in the <code>freeze()</code> function. Just make all of your internal 247 * fields frozen, and set the frozen flag. Any subsequent getter/setter will 248 * work properly. Here is an example: 249 * </p> 250 * <p><b>Warning!</b> The 'frozen' boolean MUST be volatile, and must be set as the last statement 251 * in the method.</p> 252 * <pre> 253 * public A freeze() { 254 * if (!frozen) { 255 * foo.freeze(); 256 * frozen = true; 257 * } 258 * return this; 259 * } 260 * </pre> 261 * 262 * <p> 263 * If the field is a <code>Collection</code> or <code>Map</code>, then to 264 * make it frozen you have two choices. If you have never allowed access to the 265 * collection from outside your object, then just wrap it to prevent future 266 * modification. 267 * </p> 268 * 269 * <pre> 270 * zone_to_country = Collections.unmodifiableMap(zone_to_country); 271 * </pre> 272 * 273 * <p> 274 * If you have <i>ever</i> allowed access, then do a <code>clone()</code> 275 * before wrapping it. 276 * </p> 277 * 278 * <pre> 279 * zone_to_country = Collections.unmodifiableMap(zone_to_country.clone()); 280 * </pre> 281 * 282 * <p> 283 * If a collection <i>(or any other container of objects)</i> itself can 284 * contain mutable objects, then for a safe clone you need to recurse through it 285 * to make the entire collection immutable. The recursing code should pick the 286 * most specific collection available, to avoid the necessity of later 287 * downcasing. 288 * </p> 289 * <blockquote> 290 * <p> 291 * <b>Note: </b>An annoying flaw in Java is that the generic collections, like 292 * <code>Map</code> or <code>Set</code>, don't have a <code>clone()</code> 293 * operation. When you don't know the type of the collection, the simplest 294 * course is to just create a new collection: 295 * </p> 296 * 297 * <pre> 298 * zone_to_country = Collections.unmodifiableMap(new HashMap(zone_to_country)); 299 * </pre> 300 * 301 * </blockquote> 302 * @stable ICU 3.8 303 */ 304 public interface Freezable<T> extends Cloneable { 305 /** 306 * Determines whether the object has been frozen or not. 307 * @stable ICU 3.8 308 */ isFrozen()309 public boolean isFrozen(); 310 311 /** 312 * Freezes the object. 313 * @return the object itself. 314 * @stable ICU 3.8 315 */ freeze()316 public T freeze(); 317 318 /** 319 * Provides for the clone operation. Any clone is initially unfrozen. 320 * @stable ICU 3.8 321 */ cloneAsThawed()322 public T cloneAsThawed(); 323 } 324