Create a cache for class loading that both successfully loaded classes, as well as class lookup failures (using Void.class as a null object).

This change also reworks the loading infrastructure to not throw/catch class cast exceptions since we expect cache misses in certain cases, and we want fast response to multiple lookups.