提交 9202224b 编写于 作者: A Andy Clement

SPR-8174: varargs and primitive handling in SpEL

上级 b9d07b9c
......@@ -316,18 +316,73 @@ public class ReflectionHelper {
if (argumentCount >= parameterCount) {
arraySize = argumentCount - (parameterCount - 1);
}
Object[] repackagedArguments = (Object[]) Array.newInstance(requiredParameterTypes[parameterCount - 1].getComponentType(),
arraySize);
// Copy all but the varargs arguments
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = args[parameterCount + i - 1];
}
// Create an array for the varargs arguments
Object[] newArgs = new Object[parameterCount];
for (int i = 0; i < newArgs.length - 1; i++) {
newArgs[i] = args[i];
}
newArgs[newArgs.length - 1] = repackagedArguments;
// Now sort out the final argument, which is the varargs one. Before entering this
// method the arguments should have been converted to the box form of the required type.
Class<?> componentType = requiredParameterTypes[parameterCount-1].getComponentType();
if (componentType.isPrimitive()) {
if (componentType==Integer.TYPE) {
int[] repackagedArguments = (int[]) Array.newInstance(componentType, arraySize);
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = ((Integer)args[parameterCount + i - 1]).intValue();
}
newArgs[newArgs.length - 1] = repackagedArguments;
} else if(componentType==Float.TYPE) {
float[] repackagedArguments = (float[]) Array.newInstance(componentType, arraySize);
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = ((Float)args[parameterCount + i - 1]).floatValue();
}
newArgs[newArgs.length - 1] = repackagedArguments;
} else if(componentType==Double.TYPE) {
double[] repackagedArguments = (double[]) Array.newInstance(componentType, arraySize);
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = ((Double)args[parameterCount + i - 1]).doubleValue();
}
newArgs[newArgs.length - 1] = repackagedArguments;
} else if(componentType==Short.TYPE) {
short[] repackagedArguments = (short[]) Array.newInstance(componentType, arraySize);
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = ((Short)args[parameterCount + i - 1]).shortValue();
}
newArgs[newArgs.length - 1] = repackagedArguments;
} else if(componentType==Character.TYPE) {
char[] repackagedArguments = (char[]) Array.newInstance(componentType, arraySize);
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = ((Character)args[parameterCount + i - 1]).charValue();
}
newArgs[newArgs.length - 1] = repackagedArguments;
} else if(componentType==Byte.TYPE) {
byte[] repackagedArguments = (byte[]) Array.newInstance(componentType, arraySize);
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = ((Byte)args[parameterCount + i - 1]).byteValue();
}
newArgs[newArgs.length - 1] = repackagedArguments;
} else if(componentType==Boolean.TYPE) {
boolean[] repackagedArguments = (boolean[]) Array.newInstance(componentType, arraySize);
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = ((Boolean)args[parameterCount + i - 1]).booleanValue();
}
newArgs[newArgs.length - 1] = repackagedArguments;
} else if(componentType==Long.TYPE) {
long[] repackagedArguments = (long[]) Array.newInstance(componentType, arraySize);
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = ((Long)args[parameterCount + i - 1]).longValue();
}
newArgs[newArgs.length - 1] = repackagedArguments;
}
} else {
Object[] repackagedArguments = (Object[]) Array.newInstance(componentType, arraySize);
// Copy all but the varargs arguments
for (int i = 0; i < arraySize; i++) {
repackagedArguments[i] = args[parameterCount + i - 1];
}
newArgs[newArgs.length - 1] = repackagedArguments;
}
return newArgs;
}
return args;
......
......@@ -36,11 +36,13 @@ import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.MethodExecutor;
import org.springframework.expression.ParserContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.ReflectiveMethodResolver;
import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeLocator;
......@@ -811,5 +813,109 @@ public class SpringEL300Tests extends ExpressionTestCase {
assertEquals("[D(aaa), D(bbb), D(ccc)]",value3.toString());
}
@Test
public void varargsAndPrimitives_SPR8174() throws Exception {
EvaluationContext emptyEvalContext = new StandardEvaluationContext();
List<TypeDescriptor> args = new ArrayList<TypeDescriptor>();
args.add(TypeDescriptor.forObject(34L));
ReflectionUtil<Integer> ru = new ReflectionUtil<Integer>();
MethodExecutor me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"methodToCall",args);
args.set(0,TypeDescriptor.forObject(23));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, 45);
args.set(0,TypeDescriptor.forObject(23f));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, 45f);
args.set(0,TypeDescriptor.forObject(23d));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, 23d);
args.set(0,TypeDescriptor.forObject((short)23));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, (short)23);
args.set(0,TypeDescriptor.forObject(23L));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, 23L);
args.set(0,TypeDescriptor.forObject((char)65));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, (char)65);
args.set(0,TypeDescriptor.forObject((byte)23));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, (byte)23);
args.set(0,TypeDescriptor.forObject(true));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, true);
// trickier:
args.set(0,TypeDescriptor.forObject(12));
args.add(TypeDescriptor.forObject(23f));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"bar",args);
me.execute(emptyEvalContext, ru, 12,23f);
}
public class ReflectionUtil<T extends Number> {
public Object methodToCall(T param) {
System.out.println(param+" "+param.getClass());
return "Object methodToCall(T param)";
}
public void foo(int... array) {
if (array.length==0) {
throw new RuntimeException();
}
}
public void foo(float...array) {
if (array.length==0) {
throw new RuntimeException();
}
}
public void foo(double...array) {
if (array.length==0) {
throw new RuntimeException();
}
}
public void foo(short...array) {
if (array.length==0) {
throw new RuntimeException();
}
}
public void foo(long...array) {
if (array.length==0) {
throw new RuntimeException();
}
}
public void foo(boolean...array) {
if (array.length==0) {
throw new RuntimeException();
}
}
public void foo(char...array) {
if (array.length==0) {
throw new RuntimeException();
}
}
public void foo(byte...array) {
if (array.length==0) {
throw new RuntimeException();
}
}
public void bar(int... array) {
if (array.length==0) {
throw new RuntimeException();
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册