(Method m, Object[] args)
| 713 | } |
| 714 | |
| 715 | private static Object[] adaptForVarArgs(Method m, Object[] args) { |
| 716 | if (!m.isVarArgs()) return args; |
| 717 | |
| 718 | Class<?>[] ptypes = m.getParameterTypes(); |
| 719 | int fixedCount = ptypes.length - 1; // last is the vararg array param |
| 720 | Class<?> varArrayType = ptypes[ptypes.length - 1]; // e.g. Object[] |
| 721 | Class<?> componentType = varArrayType.getComponentType(); |
| 722 | |
| 723 | // Build the final invocation array with exactly ptypes.length slots |
| 724 | Object[] invokeArgs = new Object[ptypes.length]; |
| 725 | |
| 726 | // Copy fixed arguments (or null if missing) |
| 727 | for (int i = 0; i < fixedCount; i++) { |
| 728 | invokeArgs[i] = (i < args.length) ? args[i] : null; |
| 729 | } |
| 730 | |
| 731 | // If caller already provided an array for the varargs slot AND argument count matches, |
| 732 | // keep it as-is (common case: args already has Object[]{..., new Object[]{price}}) |
| 733 | if (args.length == ptypes.length && args[fixedCount] != null && args[fixedCount].getClass().isArray()) { |
| 734 | // (Optionally) you could also check assignability to varArrayType here. |
| 735 | invokeArgs[fixedCount] = args[fixedCount]; |
| 736 | return invokeArgs; |
| 737 | } |
| 738 | |
| 739 | // Otherwise, pack remaining args into the varargs array |
| 740 | int varCount = Math.max(0, args.length - fixedCount); |
| 741 | Object varArray = Array.newInstance(componentType, varCount); |
| 742 | for (int j = 0; j < varCount; j++) { |
| 743 | Array.set(varArray, j, args[fixedCount + j]); |
| 744 | } |
| 745 | |
| 746 | invokeArgs[fixedCount] = varArray; |
| 747 | return invokeArgs; |
| 748 | } |
| 749 | |
| 750 | public static Object callDynamicallyAsync(Object obj, Object methodName, Object[] args) { |
| 751 | if (args == null) args = new Object[]{}; |
no test coverage detected