Exemplo n.º 1
0
 /**
  * Return a method handle that takes the indicated number of typed arguments and returns an array
  * of them. The type argument is the array type.
  */
 public static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
   Class<?> elemType = arrayType.getComponentType();
   if (elemType == null) throw new IllegalArgumentException("not an array: " + arrayType);
   // FIXME: Need more special casing and caching here.
   if (nargs >= MAX_JVM_ARITY / 2 - 1) {
     int slots = nargs;
     final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH
     if (arrayType == double[].class || arrayType == long[].class) slots *= 2;
     if (slots > MAX_ARRAY_SLOTS)
       throw new IllegalArgumentException(
           "too many arguments: " + arrayType.getSimpleName() + ", length " + nargs);
   }
   if (elemType == Object.class) return varargsArray(nargs);
   // other cases:  primitive arrays, subtypes of Object[]
   MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
   MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
   if (mh != null) return mh;
   if (elemType.isPrimitive()) {
     MethodHandle builder = FILL_NEW_ARRAY;
     MethodHandle producer = buildArrayProducer(arrayType);
     mh = buildVarargsArray(builder, producer, nargs);
   } else {
     @SuppressWarnings("unchecked")
     Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
     Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
     MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example);
     MethodHandle producer = ARRAY_IDENTITY;
     mh = buildVarargsArray(builder, producer, nargs);
   }
   mh =
       mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
   assert (assertCorrectArity(mh, nargs));
   if (nargs < cache.length) cache[nargs] = mh;
   return mh;
 }