static ObjectInspector getReflectionObjectInspector(Type t,
      ObjectInspectorOptions options, boolean ensureInited) {
    ObjectInspector oi = objectInspectorCache.asMap().get(t);
    if (oi == null) {
      oi = getReflectionObjectInspectorNoCache(t, options, ensureInited);
      ObjectInspector prev = objectInspectorCache.asMap().putIfAbsent(t, oi);
      if (prev != null) {
        oi = prev;
      }
    }
    if (ensureInited && oi instanceof ReflectionStructObjectInspector) {
      ReflectionStructObjectInspector soi = (ReflectionStructObjectInspector) oi;
      synchronized (soi) {
        HashSet<Type> checkedTypes = new HashSet<Type>();
        while (!soi.isFullyInited(checkedTypes)) {
          try {
            // Wait for up to 3 seconds before checking if any init error.
            // Init should be fast if no error, no need to make this configurable.
            soi.wait(3000);
          } catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while waiting for "
              + soi.getClass().getName() + " to initialize", e);
          }
        }
      }
    }
    verifyObjectInspector(options, oi, ObjectInspectorOptions.JAVA, new Class[]{ThriftStructObjectInspector.class,
      ProtocolBuffersStructObjectInspector.class});
    verifyObjectInspector(options, oi, ObjectInspectorOptions.THRIFT, new Class[]{ReflectionStructObjectInspector.class,
        ProtocolBuffersStructObjectInspector.class});
    verifyObjectInspector(options, oi, ObjectInspectorOptions.PROTOCOL_BUFFERS, new Class[]{ThriftStructObjectInspector.class,
        ReflectionStructObjectInspector.class});

    return oi;
  }
ObjectInspectorOptions describes what ObjectInspector to use. JAVA is to
use pure JAVA reflection. THRIFT is to use JAVA reflection and filter out
__isset fields, PROTOCOL_BUFFERS filters out has*.
New ObjectInspectorOptions can be added here when available.

We choose to use a single HashMap objectInspectorCache to cache all
situations for efficiency and code simplicity. And we don't expect a case
that a user need to create 2 or more different types of ObjectInspectors
for the same Java type.
serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorFactory.java