content: package com.alibaba.fastjson2.reader;
  
  import com.alibaba.fastjson2.JSONException;
  import com.alibaba.fastjson2.support.LambdaMiscCodec;
  import com.alibaba.fastjson2.util.Fnv;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.lang.reflect.Parameter;
  import java.util.Map;
  import java.util.function.BiFunction;
  import java.util.function.Function;
  
  final class FactoryFunction<T>
          implements Function<Map<Long, Object>, T> {
      final Method factoryMethod;
      final Function function;
      final BiFunction biFunction;
      final String[] paramNames;
      final long[] hashCodes;
  
      FactoryFunction(Method factoryMethod, String... paramNames) {
          this.factoryMethod = factoryMethod;
          Parameter[] parameters = factoryMethod.getParameters();
          this.paramNames = new String[parameters.length];
          this.hashCodes = new long[parameters.length];
          for (int i = 0; i < parameters.length; i++) {
              String name;
              if (i < paramNames.length) {
                  name = paramNames[i];
              } else {
                  name = parameters[i].getName();
              }
              paramNames[i] = name;
              hashCodes[i] = Fnv.hashCode64(name);
          }
  
          Function function = null;
          BiFunction biFunction = null;
          if (ObjectReaderCreator.JIT) {
              int parameterCount = factoryMethod.getParameterCount();
              if (parameterCount == 1) {
                  function = LambdaMiscCodec.createFunction(factoryMethod);
              } else if (parameterCount == 2) {
                  biFunction = LambdaMiscCodec.createBiFunction(factoryMethod);
              }
          }
          this.function = function;
          this.biFunction = biFunction;
      }
  
      @Override
      public T apply(Map<Long, Object> values) {
          if (function != null) {
              Object arg = values.get(hashCodes[0]);
              return (T) function.apply(arg);
          }
  
          if (biFunction != null) {
              Object arg0 = values.get(hashCodes[0]);
              Object arg1 = values.get(hashCodes[1]);
              return (T) biFunction.apply(arg0, arg1);
          }
  
          Object[] args = new Object[hashCodes.length];
          for (int i = 0; i < args.length; i++) {
              args[i] = values.get(hashCodes[i]);
          }
          return createInstance(args);
      }
  
      public T createInstance(Object[] args) {
          try {
              return (T) factoryMethod.invoke(null, args);
          } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
              throw new JSONException("invoke factoryMethod error", e);
          }
      }
  }
  