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.  It also turns Loader into an abstract class, vs. an interface.