1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2015 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
51
51
* methods.</li>
52
52
* </ul>
53
53
*
54
+ * <p>In addition, several methods in this class provide support for {@code static}
55
+ * fields — for example, {@link #setField(Class, String, Object)},
56
+ * {@link #getField(Class, String)}, etc.
57
+ *
54
58
* @author Sam Brannen
55
59
* @author Juergen Hoeller
56
60
* @since 2.5
@@ -66,87 +70,204 @@ public class ReflectionTestUtils {
66
70
67
71
68
72
/**
69
- * Set the {@link Field field} with the given {@code name} on the provided
70
- * {@link Object target object } to the supplied {@code value}.
73
+ * Set the {@linkplain Field field} with the given {@code name} on the
74
+ * provided {@code targetObject } to the supplied {@code value}.
71
75
*
72
- * <p>This method traverses the class hierarchy in search of the desired field.
73
- * In addition, an attempt will be made to make non-{@code public} fields
74
- * <em>accessible</em>, thus allowing one to set {@code protected},
75
- * {@code private}, and <em>package-private</em> fields.
76
+ * <p>This method delegates to {@link #setField(Object, String, Object, Class)},
77
+ * supplying {@code null} for the {@code type} argument.
76
78
*
77
- * @param target the target object on which to set the field
78
- * @param name the name of the field to set
79
+ * @param targetObject the target object on which to set the field; never {@code null}
80
+ * @param name the name of the field to set; never {@code null}
79
81
* @param value the value to set
80
- * @see ReflectionUtils#findField(Class, String, Class)
81
- * @see ReflectionUtils#makeAccessible(Field)
82
- * @see ReflectionUtils#setField(Field, Object, Object)
83
82
*/
84
- public static void setField (Object target , String name , Object value ) {
85
- setField (target , name , value , null );
83
+ public static void setField (Object targetObject , String name , Object value ) {
84
+ setField (targetObject , name , value , null );
85
+ }
86
+
87
+ /**
88
+ * Set the {@linkplain Field field} with the given {@code name}/{@code type}
89
+ * on the provided {@code targetObject} to the supplied {@code value}.
90
+ *
91
+ * <p>This method delegates to {@link #setField(Object, Class, String, Object, Class)},
92
+ * supplying {@code null} for the {@code targetClass} argument.
93
+ *
94
+ * @param targetObject the target object on which to set the field; never {@code null}
95
+ * @param name the name of the field to set; may be {@code null} if
96
+ * {@code type} is specified
97
+ * @param value the value to set
98
+ * @param type the type of the field to set; may be {@code null} if
99
+ * {@code name} is specified
100
+ */
101
+ public static void setField (Object targetObject , String name , Object value , Class <?> type ) {
102
+ setField (targetObject , null , name , value , type );
103
+ }
104
+
105
+ /**
106
+ * Set the static {@linkplain Field field} with the given {@code name} on
107
+ * the provided {@code targetClass} to the supplied {@code value}.
108
+ *
109
+ * <p>This method delegates to {@link #setField(Object, Class, String, Object, Class)},
110
+ * supplying {@code null} for the {@code targetObject} and {@code type} arguments.
111
+ *
112
+ * @param targetClass the target class on which to set the static field;
113
+ * never {@code null}
114
+ * @param name the name of the field to set; never {@code null}
115
+ * @param value the value to set
116
+ * @since 4.2
117
+ */
118
+ public static void setField (Class <?> targetClass , String name , Object value ) {
119
+ setField (null , targetClass , name , value , null );
120
+ }
121
+
122
+ /**
123
+ * Set the static {@linkplain Field field} with the given
124
+ * {@code name}/{@code type} on the provided {@code targetClass} to
125
+ * the supplied {@code value}.
126
+ *
127
+ * <p>This method delegates to {@link #setField(Object, Class, String, Object, Class)},
128
+ * supplying {@code null} for the {@code targetObject} argument.
129
+ *
130
+ * @param targetClass the target class on which to set the static field;
131
+ * never {@code null}
132
+ * @param name the name of the field to set; may be {@code null} if
133
+ * {@code type} is specified
134
+ * @param value the value to set
135
+ * @param type the type of the field to set; may be {@code null} if
136
+ * {@code name} is specified
137
+ * @since 4.2
138
+ */
139
+ public static void setField (Class <?> targetClass , String name , Object value , Class <?> type ) {
140
+ setField (null , targetClass , name , value , type );
86
141
}
87
142
88
143
/**
89
- * Set the {@link Field field} with the given {@code name} on the provided
90
- * {@link Object target object} to the supplied {@code value}.
144
+ * Set the {@linkplain Field field} with the given {@code name}/{@code type}
145
+ * on the provided {@code targetObject}/{@code targetClass} to the supplied
146
+ * {@code value}.
91
147
*
92
148
* <p>This method traverses the class hierarchy in search of the desired
93
149
* field. In addition, an attempt will be made to make non-{@code public}
94
150
* fields <em>accessible</em>, thus allowing one to set {@code protected},
95
151
* {@code private}, and <em>package-private</em> fields.
96
152
*
97
- * @param target the target object on which to set the field
98
- * @param name the name of the field to set
153
+ * @param targetObject the target object on which to set the field; may be
154
+ * {@code null} if the field is static
155
+ * @param targetClass the target class on which to set the field; may
156
+ * be {@code null} if the field is an instance field
157
+ * @param name the name of the field to set; may be {@code null} if
158
+ * {@code type} is specified
99
159
* @param value the value to set
100
- * @param type the type of the field (may be {@code null})
160
+ * @param type the type of the field to set; may be {@code null} if
161
+ * {@code name} is specified
101
162
* @see ReflectionUtils#findField(Class, String, Class)
102
163
* @see ReflectionUtils#makeAccessible(Field)
103
164
* @see ReflectionUtils#setField(Field, Object, Object)
165
+ * @since 4.2
104
166
*/
105
- public static void setField (Object target , String name , Object value , Class <?> type ) {
106
- Assert .notNull (target , "Target object must not be null" );
107
- Field field = ReflectionUtils .findField (target .getClass (), name , type );
167
+ public static void setField (Object targetObject , Class <?> targetClass , String name , Object value , Class <?> type ) {
168
+ Assert .isTrue (targetObject != null || targetClass != null ,
169
+ "Either targetObject or targetClass for the field must be specified" );
170
+
171
+ if (targetClass == null ) {
172
+ targetClass = targetObject .getClass ();
173
+ }
174
+ Field field = ReflectionUtils .findField (targetClass , name , type );
108
175
109
- // SPR-9571: inline Assert.notNull() in order to avoid accidentally invoking
110
- // toString() on a non-null target.
176
+ // Inline Assert.notNull() to avoid invoking toString() on a non-null target.
111
177
if (field == null ) {
112
- throw new IllegalArgumentException (String .format ("Could not find field [%s] of type [%s] on target [%s]" ,
113
- name , type , target ));
178
+ throw new IllegalArgumentException (String .format (
179
+ "Could not find field [%s] of type [%s] on target object [%s] or target class [%s]" , name , type ,
180
+ targetObject , targetClass ));
114
181
}
115
182
116
183
if (logger .isDebugEnabled ()) {
117
- logger .debug (String .format ("Setting field [%s] of type [%s] on target [%s] to value [%s]" , name , type ,
118
- target ,
119
- value ));
184
+ logger .debug (String .format (
185
+ "Setting field [%s] of type [%s] on target object [%s] or target class [%s] to value [%s]" , name , type ,
186
+ targetObject , targetClass , value ));
120
187
}
121
188
ReflectionUtils .makeAccessible (field );
122
- ReflectionUtils .setField (field , target , value );
189
+ ReflectionUtils .setField (field , targetObject , value );
123
190
}
124
191
125
192
/**
126
- * Get the field with the given {@code name} from the provided target object.
193
+ * Get the value of the {@linkplain Field field} with the given {@code name}
194
+ * from the provided {@code targetObject}.
195
+ *
196
+ * <p>This method delegates to {@link #getField(Object, Class, String)},
197
+ * supplying {@code null} for the {@code targetClass} argument.
198
+ *
199
+ * @param targetObject the target object from which to get the field;
200
+ * never {@code null}
201
+ * @param name the name of the field to get; never {@code null}
202
+ * @return the field's current value
203
+ * @see #getField(Class, String)
204
+ */
205
+ public static Object getField (Object targetObject , String name ) {
206
+ return getField (targetObject , null , name );
207
+ }
208
+
209
+ /**
210
+ * Get the value of the static {@linkplain Field field} with the given
211
+ * {@code name} from the provided {@code targetClass}.
212
+ *
213
+ * <p>This method delegates to {@link #getField(Object, Class, String)},
214
+ * supplying {@code null} for the {@code targetObject} argument.
215
+ *
216
+ * @param targetClass the target class from which to get the static field;
217
+ * never {@code null}
218
+ * @param name the name of the field to get; never {@code null}
219
+ * @return the field's current value
220
+ * @see #getField(Object, String)
221
+ * @since 4.2
222
+ */
223
+ public static Object getField (Class <?> targetClass , String name ) {
224
+ return getField (null , targetClass , name );
225
+ }
226
+
227
+ /**
228
+ * Get the value of the {@linkplain Field field} with the given {@code name}
229
+ * from the provided {@code targetObject}/{@code targetClass}.
127
230
*
128
231
* <p>This method traverses the class hierarchy in search of the desired
129
232
* field. In addition, an attempt will be made to make non-{@code public}
130
233
* fields <em>accessible</em>, thus allowing one to get {@code protected},
131
234
* {@code private}, and <em>package-private</em> fields.
132
235
*
133
- * @param target the target object on which to set the field
134
- * @param name the name of the field to get
236
+ * @param targetObject the target object from which to get the field; may be
237
+ * {@code null} if the field is static
238
+ * @param targetClass the target class from which to get the field; may
239
+ * be {@code null} if the field is an instance field
240
+ * @param name the name of the field to get; never {@code null}
135
241
* @return the field's current value
242
+ * @see #getField(Object, String)
243
+ * @see #getField(Class, String)
136
244
* @see ReflectionUtils#findField(Class, String, Class)
137
245
* @see ReflectionUtils#makeAccessible(Field)
138
- * @see ReflectionUtils#setField(Field, Object, Object)
246
+ * @see ReflectionUtils#getField(Field, Object, Object)
247
+ * @since 4.2
139
248
*/
140
- public static Object getField (Object target , String name ) {
141
- Assert .notNull (target , "Target object must not be null" );
142
- Field field = ReflectionUtils .findField (target .getClass (), name );
143
- Assert .notNull (field , "Could not find field [" + name + "] on target [" + target + "]" );
249
+ public static Object getField (Object targetObject , Class <?> targetClass , String name ) {
250
+ Assert .isTrue (targetObject != null || targetClass != null ,
251
+ "Either targetObject or targetClass for the field must be specified" );
252
+
253
+ if (targetClass == null ) {
254
+ targetClass = targetObject .getClass ();
255
+ }
256
+ Field field = ReflectionUtils .findField (targetClass , name );
257
+
258
+ // Inline Assert.notNull() to avoid invoking toString() on a non-null target.
259
+ if (field == null ) {
260
+ throw new IllegalArgumentException (
261
+ String .format ("Could not find field [%s] on target object [%s] or target class [%s]" , name ,
262
+ targetObject , targetClass ));
263
+ }
144
264
145
265
if (logger .isDebugEnabled ()) {
146
- logger .debug ("Getting field [" + name + "] from target [" + target + "]" );
266
+ logger .debug (String .format ("Getting field [%s] from target object [%s] or target class [%s]" , name ,
267
+ targetObject , targetClass ));
147
268
}
148
269
ReflectionUtils .makeAccessible (field );
149
- return ReflectionUtils .getField (field , target );
270
+ return ReflectionUtils .getField (field , targetObject );
150
271
}
151
272
152
273
/**
0 commit comments