A WeakHashMap works pretty much as a WeakReference coupled with a ReferenceQueue - there is zero news about this. Here is a stripped down example of how it is supposed to work:
public class ReferenceQueuePlayground {
public static void main(String[] args) {
ReferenceQueue<Referent> q = new ReferenceQueue<>();
Referent ref = new Referent();
WeakReference<Referent> weak = new WeakReference<>(ref, q);
ref = null;
// wait for GC to reclaim Referent
while (weak.get() != null) {
System.gc();
}
// this might return null, because ReferenceQueue is notified asynchronously
// but I am assuming the happy path here
Reference<? extends Referent> reference = q.poll();
// this will be false
System.out.println(reference == null);
// this will be true
System.out.println(reference.get() == null);
}
@RequiredArgsConstructor
@Getter
static class Referent {
}
}
This is exactly how WeakHashMap works - it gets notified when the referent is reclaimed and the reference is put on the ReferenceQueue. At some subsequent operation, expungeStaleEntries is called, which will basically take elements from this ReferenceQueue one by one and act on them.
The problem I have: how can it "act on them" if the referent is now gone? This is a ...HASHMap after all, so in order to remove the element, it must know it's hashCode. How can you know the hashCode for something that is now gone?