Merge branch '6.1.x'
This commit is contained in:
commit
09d8e4458c
|
|
@ -43,6 +43,7 @@ import java.util.UUID;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
|
|
@ -603,6 +604,12 @@ class DefaultConversionServiceTests {
|
|||
assertThat(result).containsExactly(1, 2, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertIntArrayToStringArray() {
|
||||
String[] result = conversionService.convert(new int[] {1, 2, 3}, String[].class);
|
||||
assertThat(result).containsExactly("1", "2", "3");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertIntegerArrayToIntegerArray() {
|
||||
Integer[] result = conversionService.convert(new Integer[] {1, 2, 3}, Integer[].class);
|
||||
|
|
@ -615,6 +622,12 @@ class DefaultConversionServiceTests {
|
|||
assertThat(result).containsExactly(1, 2, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertIntArrayToIntegerArray() {
|
||||
Integer[] result = conversionService.convert(new int[] {1, 2}, Integer[].class);
|
||||
assertThat(result).containsExactly(1, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertObjectArrayToIntegerArray() {
|
||||
Integer[] result = conversionService.convert(new Object[] {1, 2, 3}, Integer[].class);
|
||||
|
|
@ -627,15 +640,34 @@ class DefaultConversionServiceTests {
|
|||
assertThat(result).containsExactly(1, 2, 3);
|
||||
}
|
||||
|
||||
@Disabled("Primitive array to Object[] conversion is not currently supported")
|
||||
@Test
|
||||
void convertByteArrayToWrapperArray() {
|
||||
void convertIntArrayToObjectArray() {
|
||||
Object[] result = conversionService.convert(new int[] {1, 2}, Object[].class);
|
||||
assertThat(result).containsExactly(1, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertIntArrayToFloatArray() {
|
||||
Float[] result = conversionService.convert(new int[] {1, 2}, Float[].class);
|
||||
assertThat(result).containsExactly(1.0F, 2.0F);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertIntArrayToPrimitiveFloatArray() {
|
||||
float[] result = conversionService.convert(new int[] {1, 2}, float[].class);
|
||||
assertThat(result).containsExactly(1.0F, 2.0F);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertPrimitiveByteArrayToByteWrapperArray() {
|
||||
byte[] byteArray = {1, 2, 3};
|
||||
Byte[] converted = conversionService.convert(byteArray, Byte[].class);
|
||||
assertThat(converted).isEqualTo(new Byte[]{1, 2, 3});
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertArrayToArrayAssignable() {
|
||||
void convertIntArrayToIntArray() {
|
||||
int[] result = conversionService.convert(new int[] {1, 2, 3}, int[].class);
|
||||
assertThat(result).containsExactly(1, 2, 3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -383,11 +383,15 @@ public abstract class ReflectionHelper {
|
|||
conversionOccurred |= (argument != arguments[i]);
|
||||
}
|
||||
|
||||
Class<?> varArgClass = methodHandleType.lastParameterType();
|
||||
ResolvableType varArgResolvableType = ResolvableType.forClass(varArgClass);
|
||||
TypeDescriptor targetType = new TypeDescriptor(varArgResolvableType, varArgClass.componentType(), null);
|
||||
TypeDescriptor componentTypeDesc = targetType.getElementTypeDescriptor();
|
||||
Assert.state(componentTypeDesc != null, "Component type must not be null for a varargs array");
|
||||
Class<?> varargsArrayClass = methodHandleType.lastParameterType();
|
||||
// We use the wrapper type for a primitive varargs array, since we eventually
|
||||
// need an Object array in order to invoke the MethodHandle in
|
||||
// FunctionReference#executeFunctionViaMethodHandle().
|
||||
Class<?> varargsComponentClass = ClassUtils.resolvePrimitiveIfNecessary(varargsArrayClass.componentType());
|
||||
TypeDescriptor varargsArrayType = TypeDescriptor.array(TypeDescriptor.valueOf(varargsComponentClass));
|
||||
Assert.state(varargsArrayType != null, "Array type must not be null for a varargs array");
|
||||
TypeDescriptor varargsComponentType = varargsArrayType.getElementTypeDescriptor();
|
||||
Assert.state(varargsComponentType != null, "Component type must not be null for a varargs array");
|
||||
|
||||
// If the target is varargs and there is just one more argument, then convert it here.
|
||||
if (varargsPosition == arguments.length - 1) {
|
||||
|
|
@ -395,17 +399,21 @@ public abstract class ReflectionHelper {
|
|||
TypeDescriptor sourceType = TypeDescriptor.forObject(argument);
|
||||
if (argument == null) {
|
||||
// Perform the equivalent of GenericConversionService.convertNullSource() for a single argument.
|
||||
if (componentTypeDesc.getObjectType() == Optional.class) {
|
||||
if (varargsComponentType.getObjectType() == Optional.class) {
|
||||
arguments[varargsPosition] = Optional.empty();
|
||||
conversionOccurred = true;
|
||||
}
|
||||
}
|
||||
// If the argument type is assignable to the varargs component type, there is no need to
|
||||
// convert it or wrap it in an array. For example, using StringToArrayConverter to
|
||||
// convert a String containing a comma would result in the String being split and
|
||||
// repackaged in an array when it should be used as-is.
|
||||
else if (!sourceType.isAssignableTo(componentTypeDesc)) {
|
||||
arguments[varargsPosition] = converter.convertValue(argument, sourceType, targetType);
|
||||
// convert it. For example, using StringToArrayConverter to convert a String containing a
|
||||
// comma would result in the String being split and repackaged in an array when it should
|
||||
// be used as-is. Similarly, if the argument is an array that is assignable to the varargs
|
||||
// array type, there is no need to convert it.
|
||||
else if (!sourceType.isAssignableTo(varargsComponentType) ||
|
||||
(sourceType.isArray() && !sourceType.isAssignableTo(varargsArrayType))) {
|
||||
|
||||
TypeDescriptor targetTypeToUse = (sourceType.isArray() ? varargsArrayType : varargsComponentType);
|
||||
arguments[varargsPosition] = converter.convertValue(argument, sourceType, targetTypeToUse);
|
||||
}
|
||||
// Possible outcomes of the above if-else block:
|
||||
// 1) the input argument was null, and nothing was done.
|
||||
|
|
@ -423,7 +431,7 @@ public abstract class ReflectionHelper {
|
|||
for (int i = varargsPosition; i < arguments.length; i++) {
|
||||
Object argument = arguments[i];
|
||||
TypeDescriptor sourceType = TypeDescriptor.forObject(argument);
|
||||
arguments[i] = converter.convertValue(argument, sourceType, componentTypeDesc);
|
||||
arguments[i] = converter.convertValue(argument, sourceType, varargsComponentType);
|
||||
conversionOccurred |= (argument != arguments[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.lang.reflect.Method;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
|
|
@ -245,6 +246,7 @@ class MethodInvocationTests extends AbstractExpressionTests {
|
|||
evaluate("aVarargsMethod(1,'a',3.0d)", "[1, a, 3.0]", String.class); // first and last need conversion
|
||||
evaluate("aVarargsMethod(new String[]{'a','b','c'})", "[a, b, c]", String.class);
|
||||
evaluate("aVarargsMethod(new String[]{})", "[]", String.class);
|
||||
evaluate("aVarargsMethod(new int[]{1, 2, 3})", "[1, 2, 3]", String.class); // needs int[] to String[] conversion
|
||||
evaluate("aVarargsMethod(null)", "[null]", String.class);
|
||||
evaluate("aVarargsMethod(null,'a')", "[null, a]", String.class);
|
||||
evaluate("aVarargsMethod('a',null,'b')", "[a, null, b]", String.class);
|
||||
|
|
@ -320,6 +322,7 @@ class MethodInvocationTests extends AbstractExpressionTests {
|
|||
// Conversion necessary
|
||||
evaluate("formatObjectVarargs('x -> %s %s', 2, 3)", "x -> 2 3", String.class);
|
||||
evaluate("formatObjectVarargs('x -> %s %s', 'a', 3.0d)", "x -> a 3.0", String.class);
|
||||
evaluate("formatObjectVarargs('x -> %s %s %s', new Integer[]{1, 2, 3})", "x -> 1 2 3", String.class);
|
||||
|
||||
// Individual string contains a comma with multiple varargs arguments
|
||||
evaluate("formatObjectVarargs('foo -> %s %s', ',', 'baz')", "foo -> , baz", String.class);
|
||||
|
|
@ -333,6 +336,34 @@ class MethodInvocationTests extends AbstractExpressionTests {
|
|||
evaluate("formatObjectVarargs('foo -> %s', 'bar,baz')", "foo -> bar,baz", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVarargsWithPrimitiveArrayType() {
|
||||
// Calling 'public String formatPrimitiveVarargs(String format, int... nums)' -> effectively String.format(format, args)
|
||||
|
||||
// No var-args and no conversion necessary
|
||||
evaluate("formatPrimitiveVarargs(9)", "9", String.class);
|
||||
|
||||
// No var-args but conversion necessary
|
||||
evaluate("formatPrimitiveVarargs('7')", "7", String.class);
|
||||
|
||||
// No conversion necessary
|
||||
evaluate("formatPrimitiveVarargs('x -> %s', 9)", "x -> 9", String.class);
|
||||
evaluate("formatPrimitiveVarargs('x -> %s %s %s', 1, 2, 3)", "x -> 1 2 3", String.class);
|
||||
evaluate("formatPrimitiveVarargs('x -> %s', new int[]{1})", "x -> 1", String.class);
|
||||
evaluate("formatPrimitiveVarargs('x -> %s %s %s', new int[]{1, 2, 3})", "x -> 1 2 3", String.class);
|
||||
|
||||
// Conversion necessary
|
||||
evaluate("formatPrimitiveVarargs('x -> %s %s', '2', '3')", "x -> 2 3", String.class);
|
||||
evaluate("formatPrimitiveVarargs('x -> %s %s', '2', 3.0d)", "x -> 2 3", String.class);
|
||||
}
|
||||
|
||||
@Disabled("Primitive array to Object[] conversion is not currently supported")
|
||||
@Test
|
||||
void testVarargsWithPrimitiveArrayToObjectArrayConversion() {
|
||||
evaluate("formatObjectVarargs('x -> %s %s %s', new short[]{1, 2, 3})", "x -> 1 2 3", String.class); // short[] to Object[]
|
||||
evaluate("formatObjectVarargs('x -> %s %s %s', new int[]{1, 2, 3})", "x -> 1 2 3", String.class); // int[] to Object[]
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVarargsOptionalInvocation() {
|
||||
// Calling 'public String optionalVarargsMethod(Optional<String>... values)'
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ class TestScenarioCreator {
|
|||
TestScenarioCreator.class.getDeclaredMethod("varargsFunction", String[].class));
|
||||
testContext.registerFunction("varargsFunction2",
|
||||
TestScenarioCreator.class.getDeclaredMethod("varargsFunction2", int.class, String[].class));
|
||||
testContext.registerFunction("varargsObjectFunction",
|
||||
TestScenarioCreator.class.getDeclaredMethod("varargsObjectFunction", Object[].class));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
|
|
@ -106,6 +108,11 @@ class TestScenarioCreator {
|
|||
"formatObjectVarargs", MethodType.methodType(String.class, String.class, Object[].class));
|
||||
testContext.registerFunction("formatObjectVarargs", formatObjectVarargs);
|
||||
|
||||
// #formatObjectVarargs(format, args...)
|
||||
MethodHandle formatPrimitiveVarargs = MethodHandles.lookup().findStatic(TestScenarioCreator.class,
|
||||
"formatPrimitiveVarargs", MethodType.methodType(String.class, String.class, int[].class));
|
||||
testContext.registerFunction("formatPrimitiveVarargs", formatPrimitiveVarargs);
|
||||
|
||||
// #add(int, int)
|
||||
MethodHandle add = MethodHandles.lookup().findStatic(TestScenarioCreator.class,
|
||||
"add", MethodType.methodType(int.class, int.class, int.class));
|
||||
|
|
@ -160,6 +167,10 @@ class TestScenarioCreator {
|
|||
return i + "-" + Arrays.toString(strings);
|
||||
}
|
||||
|
||||
public static String varargsObjectFunction(Object... args) {
|
||||
return Arrays.toString(args);
|
||||
}
|
||||
|
||||
public static String message(String template, String... args) {
|
||||
return template.formatted((Object[]) args);
|
||||
}
|
||||
|
|
@ -168,6 +179,14 @@ class TestScenarioCreator {
|
|||
return String.format(format, args);
|
||||
}
|
||||
|
||||
public static String formatPrimitiveVarargs(String format, int... nums) {
|
||||
Object[] args = new Object[nums.length];
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
args[i] = nums[i];
|
||||
}
|
||||
return String.format(format, args);
|
||||
}
|
||||
|
||||
public static int add(int x, int y) {
|
||||
return x + y;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
|
@ -80,9 +81,11 @@ class VariableAndFunctionTests extends AbstractExpressionTests {
|
|||
evaluate("#varargsFunction(new String[0])", "[]", String.class);
|
||||
evaluate("#varargsFunction('a')", "[a]", String.class);
|
||||
evaluate("#varargsFunction('a','b','c')", "[a, b, c]", String.class);
|
||||
evaluate("#varargsFunction(new String[]{'a','b','c'})", "[a, b, c]", String.class);
|
||||
// Conversion from int to String
|
||||
evaluate("#varargsFunction(25)", "[25]", String.class);
|
||||
evaluate("#varargsFunction('b',25)", "[b, 25]", String.class);
|
||||
evaluate("#varargsFunction(new int[]{1, 2, 3})", "[1, 2, 3]", String.class);
|
||||
// Strings that contain a comma
|
||||
evaluate("#varargsFunction('a,b')", "[a,b]", String.class);
|
||||
evaluate("#varargsFunction('a', 'x,y', 'd')", "[a, x,y, d]", String.class);
|
||||
|
|
@ -103,6 +106,21 @@ class VariableAndFunctionTests extends AbstractExpressionTests {
|
|||
// null values
|
||||
evaluate("#varargsFunction2(9,null)", "9-[null]", String.class);
|
||||
evaluate("#varargsFunction2(9,'a',null,'b')", "9-[a, null, b]", String.class);
|
||||
|
||||
evaluate("#varargsObjectFunction()", "[]", String.class);
|
||||
evaluate("#varargsObjectFunction(new String[0])", "[]", String.class);
|
||||
evaluate("#varargsObjectFunction('a')", "[a]", String.class);
|
||||
evaluate("#varargsObjectFunction('a','b','c')", "[a, b, c]", String.class);
|
||||
evaluate("#varargsObjectFunction(new String[]{'a','b','c'})", "[a, b, c]", String.class);
|
||||
// Conversion from int to String
|
||||
evaluate("#varargsObjectFunction(25)", "[25]", String.class);
|
||||
evaluate("#varargsObjectFunction('b',25)", "[b, 25]", String.class);
|
||||
// Strings that contain a comma
|
||||
evaluate("#varargsObjectFunction('a,b')", "[a,b]", String.class);
|
||||
evaluate("#varargsObjectFunction('a', 'x,y', 'd')", "[a, x,y, d]", String.class);
|
||||
// null values
|
||||
evaluate("#varargsObjectFunction(null)", "[null]", String.class);
|
||||
evaluate("#varargsObjectFunction('a',null,'b')", "[a, null, b]", String.class);
|
||||
}
|
||||
|
||||
@Test // gh-33013
|
||||
|
|
@ -110,17 +128,25 @@ class VariableAndFunctionTests extends AbstractExpressionTests {
|
|||
// Calling 'public static String formatObjectVarargs(String format, Object... args)' -> String.format(format, args)
|
||||
|
||||
// No var-args and no conversion necessary
|
||||
evaluate("#message('x')", "x", String.class);
|
||||
evaluate("#formatObjectVarargs('x')", "x", String.class);
|
||||
|
||||
// No var-args but conversion necessary
|
||||
evaluate("#message(9)", "9", String.class);
|
||||
evaluate("#formatObjectVarargs(9)", "9", String.class);
|
||||
|
||||
// No conversion necessary
|
||||
evaluate("#add(3, 4)", 7, Integer.class);
|
||||
evaluate("#message('x -> %s %s %s', 'a', 'b', 'c')", "x -> a b c", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', '')", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', ' ')", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', 'a')", "x -> a", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s %s %s', 'a', 'b', 'c')", "x -> a b c", String.class);
|
||||
evaluate("#message('x -> %s %s %s', new Object[]{'a', 'b', 'c'})", "x -> a b c", String.class); // Object[] instanceof Object[]
|
||||
evaluate("#message('x -> %s %s %s', new String[]{'a', 'b', 'c'})", "x -> a b c", String.class); // String[] instanceof Object[]
|
||||
evaluate("#message('x -> %s %s %s', new Integer[]{1, 2, 3})", "x -> 1 2 3", String.class); // Integer[] instanceof Object[]
|
||||
evaluate("#formatObjectVarargs('x -> %s %s', 2, 3)", "x -> 2 3", String.class); // Integer instanceof Object
|
||||
evaluate("#formatObjectVarargs('x -> %s %s', 'a', 3.0F)", "x -> a 3.0", String.class); // String/Float instanceof Object
|
||||
evaluate("#formatObjectVarargs('x -> %s', new Object[]{''})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new String[]{''})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new Object[]{' '})", "x -> ", String.class);
|
||||
|
|
@ -131,9 +157,12 @@ class VariableAndFunctionTests extends AbstractExpressionTests {
|
|||
evaluate("#formatObjectVarargs('x -> %s %s %s', new String[]{'a', 'b', 'c'})", "x -> a b c", String.class);
|
||||
|
||||
// Conversion necessary
|
||||
evaluate("#add('2', 5.0)", 7, Integer.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s %s', 2, 3)", "x -> 2 3", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s %s', 'a', 3.0d)", "x -> a 3.0", String.class);
|
||||
evaluate("#add('2', 5.0)", 7, Integer.class); // String/Double to Integer
|
||||
evaluate("#messageStatic('x -> %s %s %s', 1, 2, 3)", "x -> 1 2 3", String.class); // Integer to String
|
||||
evaluate("#messageStatic('x -> %s %s %s', new Integer[]{1, 2, 3})", "x -> 1 2 3", String.class); // Integer[] to String[]
|
||||
evaluate("#messageStatic('x -> %s %s %s', new int[]{1, 2, 3})", "x -> 1 2 3", String.class); // int[] to String[]
|
||||
evaluate("#messageStatic('x -> %s %s %s', new short[]{1, 2, 3})", "x -> 1 2 3", String.class); // short[] to String[]
|
||||
evaluate("#formatObjectVarargs('x -> %s %s %s', new Integer[]{1, 2, 3})", "x -> 1 2 3", String.class); // Integer[] to String[]
|
||||
|
||||
// Individual string contains a comma with multiple varargs arguments
|
||||
evaluate("#formatObjectVarargs('foo -> %s %s', ',', 'baz')", "foo -> , baz", String.class);
|
||||
|
|
@ -147,6 +176,44 @@ class VariableAndFunctionTests extends AbstractExpressionTests {
|
|||
evaluate("#formatObjectVarargs('foo -> %s', 'bar,baz')", "foo -> bar,baz", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void functionWithPrimitiveVarargsViaMethodHandle() {
|
||||
// Calling 'public String formatPrimitiveVarargs(String format, int... nums)' -> effectively String.format(format, args)
|
||||
|
||||
// No var-args and no conversion necessary
|
||||
evaluate("#formatPrimitiveVarargs(9)", "9", String.class);
|
||||
|
||||
// No var-args but conversion necessary
|
||||
evaluate("#formatPrimitiveVarargs('7')", "7", String.class);
|
||||
|
||||
// No conversion necessary
|
||||
evaluate("#formatPrimitiveVarargs('x -> %s', 9)", "x -> 9", String.class);
|
||||
evaluate("#formatPrimitiveVarargs('x -> %s %s %s', 1, 2, 3)", "x -> 1 2 3", String.class);
|
||||
evaluate("#formatPrimitiveVarargs('x -> %s', new int[]{1})", "x -> 1", String.class);
|
||||
evaluate("#formatPrimitiveVarargs('x -> %s %s %s', new int[]{1, 2, 3})", "x -> 1 2 3", String.class);
|
||||
|
||||
// Conversion necessary
|
||||
evaluate("#formatPrimitiveVarargs('x -> %s %s', '2', '3')", "x -> 2 3", String.class); // String to int
|
||||
evaluate("#formatPrimitiveVarargs('x -> %s %s', '2', 3.0F)", "x -> 2 3", String.class); // String/Float to int
|
||||
evaluate("#formatPrimitiveVarargs('x -> %s %s %s', new Integer[]{1, 2, 3})", "x -> 1 2 3", String.class); // Integer[] to int[]
|
||||
evaluate("#formatPrimitiveVarargs('x -> %s %s %s', new String[]{'1', '2', '3'})", "x -> 1 2 3", String.class); // String[] to int[]
|
||||
}
|
||||
|
||||
@Disabled("Primitive array to Object[] conversion is not currently supported")
|
||||
@Test
|
||||
void functionFromMethodWithVarargsAndPrimitiveArrayToObjectArrayConversion() {
|
||||
evaluate("#varargsObjectFunction(new short[]{1, 2, 3})", "[1, 2, 3]", String.class); // short[] to Object[]
|
||||
evaluate("#varargsObjectFunction(new int[]{1, 2, 3})", "[1, 2, 3]", String.class); // int[] to Object[]
|
||||
}
|
||||
|
||||
@Disabled("Primitive array to Object[] conversion is not currently supported")
|
||||
@Test
|
||||
void functionFromMethodHandleWithVarargsAndPrimitiveArrayToObjectArrayConversion() {
|
||||
evaluate("#message('x -> %s %s %s', new short[]{1, 2, 3})", "x -> 1 2 3", String.class); // short[] to Object[]
|
||||
evaluate("#message('x -> %s %s %s', new int[]{1, 2, 3})", "x -> 1 2 3", String.class); // int[] to Object[]
|
||||
evaluate("#formatObjectVarargs('x -> %s %s %s', new int[]{1, 2, 3})", "x -> 1 2 3", String.class); // int[] to Object[]
|
||||
}
|
||||
|
||||
@Test
|
||||
void functionMethodMustBeStatic() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
|
|
|
|||
|
|
@ -221,6 +221,14 @@ public class Inventor {
|
|||
return String.format(format, args);
|
||||
}
|
||||
|
||||
public String formatPrimitiveVarargs(String format, int... nums) {
|
||||
Object[] args = new Object[nums.length];
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
args[i] = nums[i];
|
||||
}
|
||||
return String.format(format, args);
|
||||
}
|
||||
|
||||
|
||||
public Inventor(String... strings) {
|
||||
if (strings.length > 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue