Skip to content

Commit a8623db

Browse files
committed
MethodParameter.equals checks nesting level and containing class
Closes gh-23352
1 parent 4f01042 commit a8623db

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

spring-core/src/main/java/org/springframework/core/MethodParameter.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@
2929

3030
import org.springframework.util.Assert;
3131
import org.springframework.util.ClassUtils;
32+
import org.springframework.util.ObjectUtils;
3233

3334
/**
3435
* Helper class that encapsulates the specification of a method parameter, i.e. a {@link Method}
@@ -71,7 +72,7 @@ public class MethodParameter {
7172

7273
private final int parameterIndex;
7374

74-
private int nestingLevel = 1;
75+
private int nestingLevel;
7576

7677
/** Map from Integer level to Integer type index */
7778
Map<Integer, Integer> typeIndexesPerLevel;
@@ -612,7 +613,11 @@ public boolean equals(Object other) {
612613
return false;
613614
}
614615
MethodParameter otherParam = (MethodParameter) other;
615-
return (this.parameterIndex == otherParam.parameterIndex && getMember().equals(otherParam.getMember()));
616+
return (this.containingClass == otherParam.containingClass &&
617+
ObjectUtils.nullSafeEquals(this.typeIndexesPerLevel, otherParam.typeIndexesPerLevel) &&
618+
this.nestingLevel == otherParam.nestingLevel &&
619+
this.parameterIndex == otherParam.parameterIndex &&
620+
getMember().equals(otherParam.getMember()));
616621
}
617622

618623
@Override

spring-core/src/test/java/org/springframework/core/MethodParameterTests.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
2222
import java.lang.annotation.Target;
2323
import java.lang.reflect.Constructor;
2424
import java.lang.reflect.Method;
25+
import java.util.ArrayList;
2526
import java.util.concurrent.Callable;
2627

2728
import org.junit.Before;
@@ -130,6 +131,44 @@ public void genericConstructorParameterInInnerClass() throws Exception {
130131
methodParameter.getGenericParameterType());
131132
}
132133

134+
@Test
135+
public void multipleResolveParameterTypeCalls() throws Exception {
136+
Method method = ArrayList.class.getMethod("get", int.class);
137+
MethodParameter methodParameter = MethodParameter.forMethodOrConstructor(method, -1);
138+
assertEquals(Object.class, methodParameter.getParameterType());
139+
GenericTypeResolver.resolveParameterType(methodParameter, StringList.class);
140+
assertEquals(String.class, methodParameter.getParameterType());
141+
GenericTypeResolver.resolveParameterType(methodParameter, IntegerList.class);
142+
assertEquals(Integer.class, methodParameter.getParameterType());
143+
}
144+
145+
@Test
146+
public void equalsAndHashCodeConsidersContainingClass() throws Exception {
147+
Method method = ArrayList.class.getMethod("get", int.class);
148+
MethodParameter m1 = MethodParameter.forMethodOrConstructor(method, -1);
149+
MethodParameter m2 = MethodParameter.forMethodOrConstructor(method, -1);
150+
MethodParameter m3 = MethodParameter.forMethodOrConstructor(method, -1).nested();
151+
assertEquals(m1, m2);
152+
assertNotEquals(m1, m3);
153+
assertEquals(m1.hashCode(), m2.hashCode());
154+
}
155+
156+
@Test
157+
public void equalsAndHashCodeConsidersNesting() throws Exception {
158+
Method method = ArrayList.class.getMethod("get", int.class);
159+
MethodParameter m1 = MethodParameter.forMethodOrConstructor(method, -1);
160+
GenericTypeResolver.resolveParameterType(m1, StringList.class);
161+
MethodParameter m2 = MethodParameter.forMethodOrConstructor(method, -1);
162+
GenericTypeResolver.resolveParameterType(m2, StringList.class);
163+
MethodParameter m3 = MethodParameter.forMethodOrConstructor(method, -1);
164+
GenericTypeResolver.resolveParameterType(m3, IntegerList.class);
165+
MethodParameter m4 = MethodParameter.forMethodOrConstructor(method, -1);
166+
assertEquals(m1, m2);
167+
assertNotEquals(m1, m3);
168+
assertNotEquals(m1, m4);
169+
assertEquals(m1.hashCode(), m2.hashCode());
170+
}
171+
133172

134173
public int method(String p1, long p2) {
135174
return 42;
@@ -154,4 +193,12 @@ public InnerClass(@Param String s, Callable<Integer> i) {
154193
private @interface Param {
155194
}
156195

196+
@SuppressWarnings("serial")
197+
private static class StringList extends ArrayList<String> {
198+
}
199+
200+
@SuppressWarnings("serial")
201+
private static class IntegerList extends ArrayList<Integer> {
202+
}
203+
157204
}

0 commit comments

Comments
 (0)