Workaround for generic parameter types on inner class constructors
Issue: SPR-16734
This commit is contained in:
parent
a2a8d0c754
commit
51be8a7303
|
@ -419,7 +419,18 @@ public class MethodParameter {
|
|||
paramType = (method != null ? method.getGenericReturnType() : void.class);
|
||||
}
|
||||
else {
|
||||
paramType = this.executable.getGenericParameterTypes()[this.parameterIndex];
|
||||
Type[] genericParameterTypes = this.executable.getGenericParameterTypes();
|
||||
int index = this.parameterIndex;
|
||||
if (this.executable instanceof Constructor &&
|
||||
ClassUtils.isInnerClass(this.executable.getDeclaringClass()) &&
|
||||
genericParameterTypes.length == this.executable.getParameterCount() - 1) {
|
||||
// Bug in javac: type array excludes enclosing instance parameter
|
||||
// for inner classes with at least one generic constructor parameter,
|
||||
// so access it with the actual parameter index lowered by 1
|
||||
index = this.parameterIndex - 1;
|
||||
}
|
||||
paramType = (index >= 0 && index < genericParameterTypes.length ?
|
||||
genericParameterTypes[index] : getParameterType());
|
||||
}
|
||||
this.genericParameterType = paramType;
|
||||
}
|
||||
|
@ -525,12 +536,8 @@ public class MethodParameter {
|
|||
// for inner classes, so access it with the actual parameter index lowered by 1
|
||||
index = this.parameterIndex - 1;
|
||||
}
|
||||
if (index >= 0 && index < annotationArray.length) {
|
||||
paramAnns = adaptAnnotationArray(annotationArray[index]);
|
||||
}
|
||||
else {
|
||||
paramAnns = EMPTY_ANNOTATION_ARRAY;
|
||||
}
|
||||
paramAnns = (index >= 0 && index < annotationArray.length ?
|
||||
adaptAnnotationArray(annotationArray[index]) : EMPTY_ANNOTATION_ARRAY);
|
||||
this.parameterAnnotations = paramAnns;
|
||||
}
|
||||
return paramAnns;
|
||||
|
@ -770,7 +777,6 @@ public class MethodParameter {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -114,7 +115,7 @@ public class MethodParameterTests {
|
|||
|
||||
@Test // SPR-16652
|
||||
public void annotatedConstructorParameterInInnerClass() throws Exception {
|
||||
Constructor<?> constructor = InnerClass.class.getConstructor(getClass(), String.class, Integer.class);
|
||||
Constructor<?> constructor = InnerClass.class.getConstructor(getClass(), String.class, Callable.class);
|
||||
|
||||
MethodParameter methodParameter = MethodParameter.forExecutable(constructor, 0);
|
||||
assertEquals(getClass(), methodParameter.getParameterType());
|
||||
|
@ -125,10 +126,28 @@ public class MethodParameterTests {
|
|||
assertNotNull("Failed to find @Param annotation", methodParameter.getParameterAnnotation(Param.class));
|
||||
|
||||
methodParameter = MethodParameter.forExecutable(constructor, 2);
|
||||
assertEquals(Integer.class, methodParameter.getParameterType());
|
||||
assertEquals(Callable.class, methodParameter.getParameterType());
|
||||
assertNull(methodParameter.getParameterAnnotation(Param.class));
|
||||
}
|
||||
|
||||
@Test // SPR-16734
|
||||
public void genericConstructorParameterInInnerClass() throws Exception {
|
||||
Constructor<?> constructor = InnerClass.class.getConstructor(getClass(), String.class, Callable.class);
|
||||
|
||||
MethodParameter methodParameter = MethodParameter.forExecutable(constructor, 0);
|
||||
assertEquals(getClass(), methodParameter.getParameterType());
|
||||
assertEquals(getClass(), methodParameter.getGenericParameterType());
|
||||
|
||||
methodParameter = MethodParameter.forExecutable(constructor, 1);
|
||||
assertEquals(String.class, methodParameter.getParameterType());
|
||||
assertEquals(String.class, methodParameter.getGenericParameterType());
|
||||
|
||||
methodParameter = MethodParameter.forExecutable(constructor, 2);
|
||||
assertEquals(Callable.class, methodParameter.getParameterType());
|
||||
assertEquals(ResolvableType.forClassWithGenerics(Callable.class, Integer.class).getType(),
|
||||
methodParameter.getGenericParameterType());
|
||||
}
|
||||
|
||||
|
||||
public int method(String p1, long p2) {
|
||||
return 42;
|
||||
|
@ -144,7 +163,7 @@ public class MethodParameterTests {
|
|||
@SuppressWarnings("unused")
|
||||
private class InnerClass {
|
||||
|
||||
public InnerClass(@Param String s, Integer i) {
|
||||
public InnerClass(@Param String s, Callable<Integer> i) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue