/* * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * -Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Oracle nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that Software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. */ import java.io.*; import java.util.*; /** * This example shows how to use the readResolve method. * This method resolves the object * read from the stream before it is returned to the caller. * The writeReplacea method allows an object to nominate its * own replacement in the stream before the object is written. * * This example creates a symbol class for which only a single instance of * each symbol binding exists. The Symbol class defines the * readResolve method. A symbol is created from outside using the * symbollookup method, which finds and returns a symbol if one already * exists and creates one, if one does not. This assures uniqueness within * one VM. Then, when readResolve is called when the symbol is being read, * a preexisting equivalent Symbol object is substituted from the hashtable * to maintain the unique identity constraint, if such a symbol exists. * Otherwise, the new symbol is added to the hashtable and returned. This * assures uniqueness when we are dealing with more than one VM. * * * How to Run: * Compile this file: javac Substitute.java * Run this file: java Substitute * * This will print out a confirmation that the two symbols that were * serialized separately but had the same name are indeed the same symbol. * * * Compiled and Tested with JDK1.2 */ public class Substitute { /** * Basically, serialize and deserialize two symbols with the same * name and show that they are actually the same symbol. */ public static void main(String args[]) { // create a few symbols to be serialized Symbol s1 = Symbol.symbolLookup("blue"); Symbol s2 = Symbol.symbolLookup("pink"); Symbol s3 = Symbol.symbolLookup("blue"); // use these to deserialize the symbols Symbol obj1 = null, obj2 = null, obj3 = null; // serialize the symbols try { FileOutputStream fo = new FileOutputStream("symbol.tmp"); ObjectOutputStream so = new ObjectOutputStream(fo); so.writeObject(s1); so.writeObject(s2); so.writeObject(s3); so.flush(); } catch (Exception e) { System.out.println(e); System.exit(1); } // deserialize the symbols try { FileInputStream fi = new FileInputStream("symbol.tmp"); ObjectInputStream si = new ObjectInputStream(fi); obj1 = (Symbol) si.readObject(); obj2 = (Symbol) si.readObject(); obj3 = (Symbol) si.readObject(); } catch (Exception e) { System.out.println(e); System.exit(1); } // show the uniqueness if (obj1 == obj3) { System.out.println("Symbol1 and Symbol3 are the same!"); } } } /** * The class implementing the readResolve method. */ class Symbol implements Serializable { /** * @serial */ String symbolname; /* * Hashtable is **static** because we need to use the same one for * all symbol objects. */ static Hashtable ht = new Hashtable(); /** * This method serves as the constructor. It looks in the hashtable and * if that symbol exists, will return that symbol... otherwise, will * create a symbol with that name and will add it to the hashtable. This * will assure that the symbols are always unique. */ static Symbol symbolLookup(String symname) { if (ht.containsKey(symname)) { return (Symbol)(ht.get(symname)); } else { Symbol newSym = new Symbol(symname); ht.put(symname, newSym); return(newSym); } } /** * Private constructor because we want "outsiders" to use * symbolLookup instead to force uniqueness. */ private Symbol (String name) { symbolname = name; } /** * Deals with the issue of uniqueness when we are dealing with more * than one VM by adding the read symbol to the hash table, if it * isn't already there. */ public Object readResolve() throws ObjectStreamException { if (!ht.containsKey(symbolname)) ht.put(symbolname, this); return (Symbol) (ht.get(symbolname)); } }