Objects with multi-threaded access should not lazily populate a hash field

Issue. SPR-11428
(cherry picked from commit 72fe7eb)
This commit is contained in:
Juergen Hoeller
2014-02-14 20:46:34 +01:00
parent d7591c6bd7
commit 7e3c722146
3 changed files with 82 additions and 113 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@@ -44,7 +44,7 @@ public class MethodParameter {
private final Method method;
private final Constructor constructor;
private final Constructor<?> constructor;
private final int parameterIndex;
@@ -65,8 +65,6 @@ public class MethodParameter {
Map<TypeVariable, Type> typeVariableMap;
private int hash = 0;
/**
* Create a new MethodParameter for the given method, with nesting level 1.
@@ -100,7 +98,7 @@ public class MethodParameter {
* @param constructor the Constructor to specify a parameter for
* @param parameterIndex the index of the parameter
*/
public MethodParameter(Constructor constructor, int parameterIndex) {
public MethodParameter(Constructor<?> constructor, int parameterIndex) {
this(constructor, parameterIndex, 1);
}
@@ -112,7 +110,7 @@ public class MethodParameter {
* (typically 1; e.g. in case of a List of Lists, 1 would indicate the
* nested List, whereas 2 would indicate the element of the nested List)
*/
public MethodParameter(Constructor constructor, int parameterIndex, int nestingLevel) {
public MethodParameter(Constructor<?> constructor, int parameterIndex, int nestingLevel) {
Assert.notNull(constructor, "Constructor must not be null");
this.constructor = constructor;
this.parameterIndex = parameterIndex;
@@ -138,7 +136,6 @@ public class MethodParameter {
this.nestingLevel = original.nestingLevel;
this.typeIndexesPerLevel = original.typeIndexesPerLevel;
this.typeVariableMap = original.typeVariableMap;
this.hash = original.hash;
}
@@ -156,24 +153,24 @@ public class MethodParameter {
* <p>Note: Either Method or Constructor is available.
* @return the Constructor, or {@code null} if none
*/
public Constructor getConstructor() {
public Constructor<?> getConstructor() {
return this.constructor;
}
/**
* Returns the wrapped member.
* @return the member
* @return the Method or Constructor as Member
*/
private Member getMember() {
return this.method != null ? this.method : this.constructor;
return (this.method != null ? this.method : this.constructor);
}
/**
* Returns the wrapped annotated element.
* @return the annotated element
* @return the Method or Constructor as AnnotatedElement
*/
private AnnotatedElement getAnnotatedElement() {
return this.method != null ? this.method : this.constructor;
return (this.method != null ? this.method : this.constructor);
}
/**
@@ -241,12 +238,12 @@ public class MethodParameter {
Integer index = getTypeIndexForCurrentLevel();
Type arg = ((ParameterizedType) type).getActualTypeArguments()[index != null ? index : 0];
if (arg instanceof Class) {
return (Class) arg;
return (Class<?>) arg;
}
else if (arg instanceof ParameterizedType) {
arg = ((ParameterizedType) arg).getRawType();
if (arg instanceof Class) {
return (Class) arg;
return (Class<?>) arg;
}
}
}
@@ -423,29 +420,14 @@ public class MethodParameter {
}
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 (this.parameterIndex == other.parameterIndex && getMember().equals(other.getMember()));
}
return false;
}
@Override
public int hashCode() {
int result = this.hash;
if (result == 0) {
result = getMember().hashCode();
result = 31 * result + this.parameterIndex;
this.hash = result;
}
return result;
return (getMember().hashCode() * 31 + this.parameterIndex);
}
@@ -462,7 +444,7 @@ public class MethodParameter {
return new MethodParameter((Method) methodOrConstructor, parameterIndex);
}
else if (methodOrConstructor instanceof Constructor) {
return new MethodParameter((Constructor) methodOrConstructor, parameterIndex);
return new MethodParameter((Constructor<?>) methodOrConstructor, parameterIndex);
}
else {
throw new IllegalArgumentException(