On Jan 28, 2022, at 2:28 PM, Dan Heidinga <heidi...@redhat.com<mailto:heidi...@redhat.com>> wrote:
public WeakReference(T o) { if (o.getClass().isValue()) throw IAE; referent = o; } That kind of check is easy to miss (or assume isn't required) based on a straightforward reading of the source code. I like the IO/VO interfaces as they let us put the constraints "must be identity (or not)" in the type system but having them as interfaces means the guarantees aren't strictly enforced by the runtime. A useful observation, thanks! We should be careful not to fall into the trap of thinking 'IdentityObject' as a type guarantees that you're not operating on a value object, where such a guarantee would be important. Even if you recognize the problem, it can be hard to address it in source. This won't catch it (replace "Runnable" with whatever interface you care about): void test(Runnable r) { this.r = (Runnable) r; // javac ignores "redundant" cast } This will: void test(Runnable r) { if (r instanceof Runnable) { this.r = r; } else { throw new ClassCastException(); } }