
class Program {
    public static void main(String[] args){
		System.out.printf("zow = %h \n", Zow.ZOW_SINGLETON_REF.getZow());

		ZowReference refZowTwo = Zow.ZOW_SINGLETON_REF.getZow().dive(Zow.ZOW_SINGLETON_REF);
		System.out.printf("zow2 = zow.dive(zow); %h ← %h\n", refZowTwo.getZow(), Zow.ZOW_SINGLETON_REF.getZow());

		ZowReference refZowThree = Zow.ZOW_SINGLETON_REF;
		System.out.printf("zowOne == zowTwo : %s\n", Zow.ZOW_SINGLETON_REF.getZow() == refZowTwo.getZow());
		System.out.printf("zowOne == zowThree : %s\n", Zow.ZOW_SINGLETON_REF.getZow() == refZowThree.getZow());
	}
}

class Zow {
	private static final Zow zowSingleton = new Zow();
	
	public static final ZowReference ZOW_SINGLETON_REF = new ZowReference(zowSingleton);

	public ZowReference dive(ZowReference refZow2) {
		System.out.printf("zow2 = %h\n", refZow2.getZow());
		refZow2.setZow(new Zow()); // compile error.
		System.out.printf("zow2 = %h\n", refZow2.getZow());

		return refZow2;
	}
}

class ZowReference {
	private final Zow zow;

	public ZowReference(Zow zow) {
		this.zow = zow;
	}

	public Zow getZow() {
		return this.zow;
	}
}


