Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 47ec4f0

Browse files
committed
Fix TypeInformation.OBJECT initialization.
We now create a decoupled instance of ClassTypeInformation to avoid initialization visibility cycle issues when TypeInformation.OBJECT (and other fields) are initialized with null because ClassTypeInformation.OBJECT hasn't been initialized yet. Closes #3340
1 parent ec792a2 commit 47ec4f0

File tree

3 files changed

+52
-25
lines changed

3 files changed

+52
-25
lines changed

‎src/main/java/org/springframework/data/util/ClassTypeInformation.java

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package org.springframework.data.util;
1717

18-
import java.util.Collection;
1918
import java.util.List;
2019
import java.util.Map;
2120
import java.util.Set;
@@ -40,23 +39,12 @@ class ClassTypeInformation<S> extends TypeDiscoverer<S> {
4039
private static final ConcurrentLruCache<Class<?>, ResolvableType> resolvableTypeCache = new ConcurrentLruCache<>(128,
4140
ResolvableType::forClass);
4241

43-
public static final ClassTypeInformation<Collection> COLLECTION;
44-
public static final ClassTypeInformation<List> LIST;
45-
public static final ClassTypeInformation<Set> SET;
46-
public static final ClassTypeInformation<Map> MAP;
47-
public static final ClassTypeInformation<Object> OBJECT;
48-
49-
static {
42+
private final Class<S> type;
5043

51-
OBJECT = from(Object.class);
52-
COLLECTION = from(Collection.class);
53-
LIST = from(List.class);
54-
SET = from(Set.class);
55-
MAP = from(Map.class);
44+
ClassTypeInformation(Class<?> type) {
45+
this(ResolvableType.forType(type));
5646
}
5747

58-
private final Class<S> type;
59-
6048
ClassTypeInformation(ResolvableType type) {
6149
super(type);
6250
this.type = (Class<S>) type.resolve(Object.class);
@@ -68,13 +56,34 @@ class ClassTypeInformation<S> extends TypeDiscoverer<S> {
6856
* @return
6957
*/
7058
public static <S> ClassTypeInformation<S> from(Class<S> type) {
59+
60+
if (type == Object.class) {
61+
return (ClassTypeInformation<S>) TypeInformation.OBJECT;
62+
} else if (type == List.class) {
63+
return (ClassTypeInformation<S>) TypeInformation.LIST;
64+
} else if (type == Set.class) {
65+
return (ClassTypeInformation<S>) TypeInformation.SET;
66+
} else if (type == Map.class) {
67+
return (ClassTypeInformation<S>) TypeInformation.MAP;
68+
}
69+
7170
return from(resolvableTypeCache.get(type));
7271
}
7372

7473
static <S> ClassTypeInformation<S> from(ResolvableType type) {
7574

7675
Assert.notNull(type, "Type must not be null");
7776

77+
if (type.getType() == Object.class) {
78+
return (ClassTypeInformation<S>) TypeInformation.OBJECT;
79+
} else if (type.getType() == List.class) {
80+
return (ClassTypeInformation<S>) TypeInformation.LIST;
81+
} else if (type.getType() == Set.class) {
82+
return (ClassTypeInformation<S>) TypeInformation.SET;
83+
} else if (type.getType() == Map.class) {
84+
return (ClassTypeInformation<S>) TypeInformation.MAP;
85+
}
86+
7887
return (ClassTypeInformation<S>) cache.get(type);
7988
}
8089

‎src/main/java/org/springframework/data/util/TypeInformation.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@
4242
*/
4343
public interface TypeInformation<S> {
4444

45-
TypeInformation<Collection> COLLECTION = ClassTypeInformation.COLLECTION;
46-
TypeInformation<List> LIST = ClassTypeInformation.LIST;
47-
TypeInformation<Set> SET = ClassTypeInformation.SET;
48-
TypeInformation<Map> MAP = ClassTypeInformation.MAP;
49-
TypeInformation<Object> OBJECT = ClassTypeInformation.OBJECT;
45+
@SuppressWarnings("rawtypes") TypeInformation<Collection> COLLECTION = newClassTypeInformation<>(Collection.class);
46+
@SuppressWarnings("rawtypes") TypeInformation<List> LIST = newClassTypeInformation<>(List.class);
47+
@SuppressWarnings("rawtypes") TypeInformation<Set> SET = newClassTypeInformation<>(Set.class);
48+
@SuppressWarnings("rawtypes") TypeInformation<Map> MAP = newClassTypeInformation<>(Map.class);
49+
TypeInformation<Object> OBJECT = newClassTypeInformation<>(Object.class);
5050

5151
/**
5252
* Creates a new {@link TypeInformation} from the given {@link ResolvableType}.
@@ -55,7 +55,7 @@ public interface TypeInformation<S> {
5555
* @return will never be {@literal null}.
5656
* @since 3.0
5757
*/
58-
publicstatic TypeInformation<?> of(ResolvableType type) {
58+
static TypeInformation<?> of(ResolvableType type) {
5959

6060
Assert.notNull(type, "Type must not be null");
6161

@@ -70,7 +70,7 @@ public static TypeInformation<?> of(ResolvableType type) {
7070
* @return will never be {@literal null}.
7171
* @since 3.0
7272
*/
73-
publicstatic <S> TypeInformation<S> of(Class<S> type) {
73+
static <S> TypeInformation<S> of(Class<S> type) {
7474

7575
Assert.notNull(type, "Type must not be null");
7676

@@ -84,7 +84,7 @@ public static <S> TypeInformation<S> of(Class<S> type) {
8484
* @return will never be {@literal null}.
8585
* @since 3.0
8686
*/
87-
publicstatic TypeInformation<?> fromReturnTypeOf(Method method) {
87+
static TypeInformation<?> fromReturnTypeOf(Method method) {
8888

8989
Assert.notNull(method, "Method must not be null");
9090

@@ -99,7 +99,7 @@ public static TypeInformation<?> fromReturnTypeOf(Method method) {
9999
* @return will never be {@literal null}.
100100
* @since 3.0
101101
*/
102-
publicstatic TypeInformation<?> fromReturnTypeOf(Method method, @Nullable Class<?> type) {
102+
static TypeInformation<?> fromReturnTypeOf(Method method, @Nullable Class<?> type) {
103103

104104
ResolvableType intermediate = type == null ? ResolvableType.forMethodReturnType(method)
105105
: ResolvableType.forMethodReturnType(method, type);
@@ -114,7 +114,7 @@ public static TypeInformation<?> fromReturnTypeOf(Method method, @Nullable Class
114114
* @return will never be {@literal null}.
115115
* @since 3.0
116116
*/
117-
publicstatic TypeInformation<?> fromMethodParameter(MethodParameter parameter) {
117+
static TypeInformation<?> fromMethodParameter(MethodParameter parameter) {
118118
return TypeInformation.of(ResolvableType.forMethodParameter(parameter));
119119
}
120120

‎src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,24 @@
4545
*/
4646
public class ClassTypeInformationUnitTests {
4747

48+
@Test // GH-3340
49+
void typeInformationConstantsShouldNotBeNull() {
50+
51+
assertThat(ClassTypeInformation.COLLECTION).isNotNull();
52+
assertThat(TypeInformation.COLLECTION).isNotNull();
53+
assertThat(TypeInformation.LIST).isNotNull();
54+
assertThat(TypeInformation.SET).isNotNull();
55+
assertThat(TypeInformation.MAP).isNotNull();
56+
assertThat(TypeInformation.OBJECT).isNotNull();
57+
assertThat(ClassTypeInformation.OBJECT).isNotNull();
58+
59+
assertThat(TypeInformation.COLLECTION).isEqualTo(ClassTypeInformation.COLLECTION);
60+
assertThat(TypeInformation.LIST).isEqualTo(ClassTypeInformation.LIST);
61+
assertThat(TypeInformation.SET).isEqualTo(ClassTypeInformation.SET);
62+
assertThat(TypeInformation.MAP).isEqualTo(ClassTypeInformation.MAP);
63+
assertThat(TypeInformation.OBJECT).isEqualTo(ClassTypeInformation.OBJECT);
64+
}
65+
4866
@Test
4967
public void discoversTypeForSimpleGenericField() {
5068

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /