private static String generateCacheKey(Type type, String prefix) {
        StringBuilder decoderClassName = new StringBuilder(prefix);
        if (type instanceof Class) {
            Class clazz = (Class) type;
            if (clazz.isAnonymousClass()) {
                throw new JsonException("anonymous class not supported: " + clazz);
            }
            if (clazz.isArray()) {
                decoderClassName.append(clazz.getCanonicalName().replace("[]", "_array"));
            } else {
                // for nested class $
                decoderClassName.append(clazz.getName().replace("[]", "_array"));
            }
        } else if (type instanceof ParameterizedType) {
            try {
                ParameterizedType pType = (ParameterizedType) type;
                Class clazz = (Class) pType.getRawType();
                decoderClassName.append(clazz.getCanonicalName().replace("[]", "_array"));
                for (int i = 0; i < pType.getActualTypeArguments().length; i++) {
                    String typeName = formatTypeWithoutSpecialCharacter(pType.getActualTypeArguments()[i]);
                    decoderClassName.append('_');
                    decoderClassName.append(typeName);
                }
            } catch (JsonException e) {
                throw e;
            } catch (Exception e) {
                throw new JsonException("failed to generate cache key for: " + type, e);
            }
        } else if (type instanceof GenericArrayType) {
            GenericArrayType gaType = (GenericArrayType) type;
            Type compType = gaType.getGenericComponentType();
            decoderClassName.append(formatTypeWithoutSpecialCharacter(compType));
            decoderClassName.append("_array");
        } else if (type instanceof WildcardType) {
            decoderClassName.append(Object.class.getName());
        } else {
            throw new UnsupportedOperationException("do not know how to handle: " + type);
        }
        return decoderClassName.toString().replace("$", "_");
    }
Constructs a new type literal. Derives represented class from type parameter.
Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
src/main/java/com/jsoniter/spi/TypeLiteral.java