Added equals and hashcode

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4029 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Arjen Poutsma 2011-02-22 13:33:24 +00:00
parent dcc91fc32a
commit 237b9b509d
2 changed files with 146 additions and 7 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2010 the original author or authors. * Copyright 2002-2011 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +17,9 @@
package org.springframework.core; package org.springframework.core;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable; import java.lang.reflect.TypeVariable;
@ -39,9 +41,9 @@ import org.springframework.util.Assert;
*/ */
public class MethodParameter { public class MethodParameter {
private Method method; private final Method method;
private Constructor constructor; private final Constructor constructor;
private final int parameterIndex; private final int parameterIndex;
@ -62,6 +64,9 @@ public class MethodParameter {
Map<TypeVariable, Type> typeVariableMap; Map<TypeVariable, Type> typeVariableMap;
private int hash;
/** /**
* Create a new MethodParameter for the given method, with nesting level 1. * Create a new MethodParameter for the given method, with nesting level 1.
@ -87,6 +92,7 @@ public class MethodParameter {
this.method = method; this.method = method;
this.parameterIndex = parameterIndex; this.parameterIndex = parameterIndex;
this.nestingLevel = nestingLevel; this.nestingLevel = nestingLevel;
this.constructor = null;
} }
/** /**
@ -111,6 +117,7 @@ public class MethodParameter {
this.constructor = constructor; this.constructor = constructor;
this.parameterIndex = parameterIndex; this.parameterIndex = parameterIndex;
this.nestingLevel = nestingLevel; this.nestingLevel = nestingLevel;
this.method = null;
} }
/** /**
@ -147,11 +154,27 @@ public class MethodParameter {
return this.constructor; return this.constructor;
} }
/**
* Returns the wrapped member.
* @return the member
*/
private Member getMember() {
return this.method != null ? this.method : this.constructor;
}
/**
* Returns the wrapped annotated element.
* @return the annotated element
*/
private AnnotatedElement getAnnotatedElement() {
return this.method != null ? this.method : this.constructor;
}
/** /**
* Return the class that declares the underlying Method or Constructor. * Return the class that declares the underlying Method or Constructor.
*/ */
public Class getDeclaringClass() { public Class getDeclaringClass() {
return (this.method != null ? this.method.getDeclaringClass() : this.constructor.getDeclaringClass()); return getMember().getDeclaringClass();
} }
/** /**
@ -209,7 +232,7 @@ public class MethodParameter {
* Return the annotations associated with the target method/constructor itself. * Return the annotations associated with the target method/constructor itself.
*/ */
public Annotation[] getMethodAnnotations() { public Annotation[] getMethodAnnotations() {
return (this.method != null ? this.method.getAnnotations() : this.constructor.getAnnotations()); return getAnnotatedElement().getAnnotations();
} }
/** /**
@ -219,8 +242,7 @@ public class MethodParameter {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends Annotation> T getMethodAnnotation(Class<T> annotationType) { public <T extends Annotation> T getMethodAnnotation(Class<T> annotationType) {
return (this.method != null ? this.method.getAnnotation(annotationType) : return getAnnotatedElement().getAnnotation(annotationType);
(T) this.constructor.getAnnotation(annotationType));
} }
/** /**
@ -374,4 +396,36 @@ public class MethodParameter {
} }
} }
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj != null && obj instanceof MethodParameter) {
MethodParameter other = (MethodParameter) obj;
if (this.parameterIndex != other.parameterIndex) {
return false;
}
else if (this.getMember().equals(other.getMember())) {
return true;
}
else {
return false;
}
}
return false;
}
@Override
public int hashCode() {
int result = hash;
if (result == 0) {
result = getMember().hashCode();
result = 31 * result + parameterIndex;
hash = result;
}
return result;
}
} }

View File

@ -0,0 +1,85 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* @author Arjen Poutsma
*/
public class MethodParameterTests {
private MethodParameter stringParameter;
private MethodParameter longParameter;
private MethodParameter intReturnType;
@Before
public void setUp() throws NoSuchMethodException {
Method method = getClass().getMethod("method", String.class, Long.TYPE);
stringParameter = new MethodParameter(method, 0);
longParameter = new MethodParameter(method, 1);
intReturnType = new MethodParameter(method, -1);
}
@Test
public void testEquals() throws NoSuchMethodException {
assertEquals(stringParameter, stringParameter);
assertEquals(longParameter, longParameter);
assertEquals(intReturnType, intReturnType);
assertFalse(stringParameter.equals(longParameter));
assertFalse(stringParameter.equals(intReturnType));
assertFalse(longParameter.equals(stringParameter));
assertFalse(longParameter.equals(intReturnType));
assertFalse(intReturnType.equals(stringParameter));
assertFalse(intReturnType.equals(longParameter));
Method method = getClass().getMethod("method", String.class, Long.TYPE);
MethodParameter methodParameter = new MethodParameter(method, 0);
assertEquals(stringParameter, methodParameter);
assertEquals(methodParameter, stringParameter);
assertFalse(longParameter.equals(methodParameter));
assertFalse(methodParameter.equals(longParameter));
}
@Test
public void testHashCode() throws NoSuchMethodException {
assertEquals(stringParameter.hashCode(), stringParameter.hashCode());
assertEquals(longParameter.hashCode(), longParameter.hashCode());
assertEquals(intReturnType.hashCode(), intReturnType.hashCode());
Method method = getClass().getMethod("method", String.class, Long.TYPE);
MethodParameter methodParameter = new MethodParameter(method, 0);
assertEquals(stringParameter.hashCode(), methodParameter.hashCode());
assertTrue(longParameter.hashCode() != methodParameter.hashCode());
}
public int method(String p1, long p2) {
return 42;
}
}