content: package com.alibaba.fastjson.issue_1700.issue1763_2;
  
  import com.alibaba.fastjson.TypeReference;
  import com.alibaba.fastjson.util.ParameterizedTypeImpl;
  import com.alibaba.fastjson.util.TypeUtils;
  
  import java.lang.reflect.GenericArrayType;
  import java.lang.reflect.ParameterizedType;
  import java.lang.reflect.Type;
  import java.lang.reflect.TypeVariable;
  import java.util.List;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.concurrent.ConcurrentMap;
  
  public class TypeReferenceBug1763_2<T> {
      static ConcurrentMap<Type, Type> classTypeCache
              = new ConcurrentHashMap<Type, Type>(16, 0.75f, 1);
  
      protected final Type type;
  
      /**
       * Constructs a new type literal. Derives represented class from type
       * parameter.
       *
       * <p>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.
       */
      protected TypeReferenceBug1763_2() {
          Type superClass = getClass().getGenericSuperclass();
  
          Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
  
          Type cachedType = classTypeCache.get(type);
          if (cachedType == null) {
              classTypeCache.putIfAbsent(type, type);
              cachedType = classTypeCache.get(type);
          }
  
          this.type = cachedType;
      }
  
      /**
       * @param actualTypeArguments
       * @since 1.2.9
       */
      protected TypeReferenceBug1763_2(Type... actualTypeArguments) {
          Class<?> thisClass = this.getClass();
          Type superClass = thisClass.getGenericSuperclass();
  
          ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0];
          Type rawType = argType.getRawType();
          Type[] argTypes = argType.getActualTypeArguments();
  
          int actualIndex = 0;
          for (int i = 0; i < argTypes.length; ++i) {
              if (argTypes[i] instanceof TypeVariable &&
                      actualIndex < actualTypeArguments.length) {
                  argTypes[i] = actualTypeArguments[actualIndex++];
              }
              // fix for openjdk and android env
              if (argTypes[i] instanceof GenericArrayType) {
                  argTypes[i] = TypeUtils.checkPrimitiveArray(
                          (GenericArrayType) argTypes[i]);
              }
          }
  
          Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType);
          Type cachedType = classTypeCache.get(key);
          if (cachedType == null) {
              classTypeCache.putIfAbsent(key, key);
              cachedType = classTypeCache.get(key);
          }
  
          type = cachedType;
      }
  
      /**
       * Gets underlying {@code Type} instance.
       */
      public Type getType() {
          return type;
      }
  
      public static final Type LIST_STRING = new TypeReference<List<String>>() {
      }.getType();
  }
  