0
# Reflection Utilities
1
2
This document covers the advanced reflection capabilities in the `org.keycloak.common.util.reflections` package that provide comprehensive utilities for type resolution, method invocation, field access, and annotation handling.
3
4
## Reflections Utility Class
5
6
The `Reflections` class provides comprehensive utility methods for reflection operations, offering a higher-level API over Java's reflection capabilities.
7
8
### Type Casting and Validation
9
10
```java { .api }
11
public class Reflections {
12
/**
13
* Runtime cast utility with improved type safety
14
*/
15
public static <T> T cast(Object obj);
16
17
/**
18
* Checks if a class is serializable
19
*/
20
public static boolean isSerializable(Class<?> clazz);
21
22
/**
23
* Extracts raw type from parameterized types
24
*/
25
public static <T> Class<T> getRawType(Type type);
26
27
/**
28
* Checks if type is array type
29
*/
30
public static boolean isArrayType(Class<?> rawType);
31
32
/**
33
* Checks if type is parameterized type
34
*/
35
public static boolean isParameterizedType(Class<?> type);
36
}
37
```
38
39
### Field Operations
40
41
```java { .api }
42
public class Reflections {
43
/**
44
* Gets all declared fields in class hierarchy
45
*/
46
public static Set<Field> getAllDeclaredFields(Class<?> clazz);
47
48
/**
49
* Finds field by name in class hierarchy
50
*/
51
public static Field findDeclaredField(Class<?> clazz, String name);
52
53
/**
54
* Gets field value from instance
55
*/
56
public static Object getFieldValue(Field field, Object instance);
57
58
/**
59
* Gets typed field value from instance
60
*/
61
public static <T> T getFieldValue(Field field, Object instance, Class<T> expectedType);
62
63
/**
64
* Resolves list element type from field
65
*/
66
public static Class<?> resolveListType(Field field, Object instance);
67
}
68
```
69
70
### Method Operations
71
72
```java { .api }
73
public class Reflections {
74
/**
75
* Checks if method exists in class
76
*/
77
public static boolean methodExists(Class<?> clazz, String name);
78
79
/**
80
* Gets all declared methods in class hierarchy
81
*/
82
public static Set<Method> getAllDeclaredMethods(Class<?> clazz);
83
84
/**
85
* Finds method by name and parameter types
86
*/
87
public static Method findDeclaredMethod(Class<?> clazz, String name, Class<?>... args);
88
89
/**
90
* Invokes method on instance
91
*/
92
public static Object invokeMethod(Method method, Object instance, Object... args);
93
94
/**
95
* Invokes method with type checking and accessibility control
96
*/
97
public static <T> T invokeMethod(boolean setAccessible, Method method, Class<T> expectedReturnType, Object instance, Object... args);
98
99
/**
100
* Gets JavaBean property name from getter method
101
*/
102
public static String getPropertyName(Method method);
103
}
104
```
105
106
### Constructor Operations
107
108
```java { .api }
109
public class Reflections {
110
/**
111
* Finds constructor by parameter types
112
*/
113
public static Constructor<?> findDeclaredConstructor(Class<?> clazz, Class<?>... args);
114
115
/**
116
* Gets all declared constructors
117
*/
118
public static Set<Constructor<?>> getAllDeclaredConstructors(Class<?> clazz);
119
120
/**
121
* Creates new instance (deprecated, use Constructor.newInstance())
122
*/
123
@Deprecated
124
public static <T> T newInstance(Class<T> fromClass);
125
}
126
```
127
128
### Accessibility Control
129
130
```java { .api }
131
public class Reflections {
132
/**
133
* Sets accessible flag on member
134
*/
135
public static <A extends AccessibleObject> A setAccessible(A member);
136
137
/**
138
* Unsets accessible flag on member
139
*/
140
public static <A extends AccessibleObject> A unsetAccessible(A member);
141
}
142
```
143
144
### Annotation Processing
145
146
```java { .api }
147
public class Reflections {
148
/**
149
* Gets annotations with specified meta-annotation
150
*/
151
public static Set<Annotation> getAnnotationsWithMetaAnnotation(Set<Annotation> annotations, Class<? extends Annotation> metaAnnotationType);
152
153
/**
154
* Checks if annotations are cacheable
155
*/
156
public static boolean isCacheable(Set<Annotation> annotations);
157
}
158
```
159
160
### Class Loading and Type Utilities
161
162
```java { .api }
163
public class Reflections {
164
/**
165
* Loads class by name with multiple class loaders
166
*/
167
public static <T> Class<T> classForName(String name, ClassLoader... loaders);
168
169
/**
170
* Gets member type (field type, method return type, etc.)
171
*/
172
public static Class<?> getMemberType(Member member);
173
174
/**
175
* Builds type map from set of types
176
*/
177
public static Map<Class<?>, Type> buildTypeMap(Set<Type> types);
178
}
179
```
180
181
### Modifier Checking
182
183
```java { .api }
184
public class Reflections {
185
/**
186
* Checks if class is final
187
*/
188
public static boolean isFinal(Class<?> clazz);
189
190
/**
191
* Checks if member is final
192
*/
193
public static boolean isFinal(Member member);
194
195
/**
196
* Checks if member is private
197
*/
198
public static boolean isPrivate(Member member);
199
200
/**
201
* Checks if type is static
202
*/
203
public static boolean isStatic(Class<?> type);
204
205
/**
206
* Checks if member is static
207
*/
208
public static boolean isStatic(Member member);
209
210
/**
211
* Checks if member is transient
212
*/
213
public static boolean isTransient(Member member);
214
215
/**
216
* Checks if method is abstract
217
*/
218
public static boolean isAbstract(Method method);
219
}
220
```
221
222
### Type Assignability
223
224
```java { .api }
225
public class Reflections {
226
/**
227
* Checks complex type assignability with generics
228
*/
229
public static boolean isAssignableFrom(Class<?> rawType1, Type[] actualTypeArguments1, Class<?> rawType2, Type[] actualTypeArguments2);
230
}
231
```
232
233
### Constants
234
235
```java { .api }
236
public class Reflections {
237
public static final Annotation[] EMPTY_ANNOTATION_ARRAY;
238
public static final Object[] EMPTY_OBJECT_ARRAY;
239
public static final Type[] EMPTY_TYPES;
240
public static final Class<?>[] EMPTY_CLASSES;
241
}
242
```
243
244
## Types Utility Class
245
246
The `Types` class provides advanced type resolution and generic type manipulation utilities.
247
248
### Basic Type Operations
249
250
```java { .api }
251
public class Types {
252
/**
253
* Gets boxed type for primitives
254
*/
255
public static Type boxedType(Type type);
256
257
/**
258
* Gets boxed class for primitive types
259
*/
260
public static Class<?> boxedClass(Class<?> type);
261
262
/**
263
* Gets raw type from generic type
264
*/
265
public static Class<?> getRawType(Type type);
266
267
/**
268
* Gets raw type without throwing exceptions
269
*/
270
public static Class<?> getRawTypeNoException(Type type);
271
}
272
```
273
274
### Generic Type Resolution
275
276
```java { .api }
277
public class Types {
278
/**
279
* Gets first type argument from generic type
280
*/
281
public static Class<?> getTypeArgument(Type genericType);
282
283
/**
284
* Gets type argument at specific index from parameterized type
285
*/
286
public static Class getArgumentType(ParameterizedType pType, int index);
287
288
/**
289
* Resolves type variables in context of root class
290
*/
291
public static Type resolveTypeVariables(Class<?> root, Type type);
292
293
/**
294
* Resolves single type variable in context of root class
295
*/
296
public static Type resolveTypeVariable(Class<?> root, TypeVariable<?> typeVariable);
297
}
298
```
299
300
### Collection Type Resolution
301
302
```java { .api }
303
public class Types {
304
/**
305
* Gets collection element type
306
*/
307
public static Class getCollectionBaseType(Class type, Type genericType);
308
309
/**
310
* Gets map key type
311
*/
312
public static Class getMapKeyType(Type genericType);
313
314
/**
315
* Gets map value type
316
*/
317
public static Class getMapValueType(Type genericType);
318
}
319
```
320
321
### Interface and Inheritance Analysis
322
323
```java { .api }
324
public class Types {
325
/**
326
* Checks if class is assignable from parameterized type
327
*/
328
public static boolean isA(Class clazz, ParameterizedType pType);
329
330
/**
331
* Gets template parameter of interface
332
*/
333
public static Class getTemplateParameterOfInterface(Class base, Class desiredInterface);
334
335
/**
336
* Gets actual type arguments of interface
337
*/
338
public static Type[] getActualTypeArgumentsOfAnInterface(Class<?> classToSearch, Class<?> interfaceToFind);
339
340
/**
341
* Finds parameterized types in class hierarchy
342
*/
343
public static Type[] findParameterizedTypes(Class<?> root, Class<?> searchedFor);
344
}
345
```
346
347
### Method Compatibility and Implementation
348
349
```java { .api }
350
public class Types {
351
/**
352
* Checks if two methods are compatible
353
*/
354
public static boolean isCompatible(Method method, Method intfMethod);
355
356
/**
357
* Gets implementing method for interface method
358
*/
359
public static Method getImplementingMethod(Class clazz, Method intfMethod);
360
}
361
```
362
363
### Type Support Checking
364
365
```java { .api }
366
public class Types {
367
/**
368
* Checks if type supports object from interface
369
*/
370
public static <T> boolean supports(Class<T> type, Object object, Class<?> fromInterface);
371
}
372
```
373
374
## Privileged Actions
375
376
Security-related classes for setting accessibility with appropriate permissions.
377
378
### SetAccessiblePrivilegedAction
379
380
```java { .api }
381
public class SetAccessiblePrivilegedAction implements PrivilegedAction<Void> {
382
public SetAccessiblePrivilegedAction(AccessibleObject accessibleObject);
383
public Void run();
384
}
385
```
386
387
### UnSetAccessiblePrivilegedAction
388
389
```java { .api }
390
public class UnSetAccessiblePrivilegedAction implements PrivilegedAction<Void> {
391
public UnSetAccessiblePrivilegedAction(AccessibleObject accessibleObject);
392
public Void run();
393
}
394
```
395
396
## Usage Examples
397
398
### Field Access and Manipulation
399
400
```java
401
// Get all fields in class hierarchy
402
Class<?> clazz = MyClass.class;
403
Set<Field> allFields = Reflections.getAllDeclaredFields(clazz);
404
405
// Find specific field
406
Field nameField = Reflections.findDeclaredField(clazz, "name");
407
408
// Access field value safely
409
Object instance = new MyClass();
410
Reflections.setAccessible(nameField);
411
String name = Reflections.getFieldValue(nameField, instance, String.class);
412
413
// Resolve generic field types
414
Field listField = Reflections.findDeclaredField(clazz, "items");
415
Class<?> elementType = Reflections.resolveListType(listField, instance);
416
```
417
418
### Method Invocation
419
420
```java
421
// Find and invoke methods
422
Class<?> clazz = MyService.class;
423
Method method = Reflections.findDeclaredMethod(clazz, "processData", String.class, int.class);
424
425
Object service = new MyService();
426
String result = Reflections.invokeMethod(true, method, String.class, service, "data", 42);
427
428
// Check method existence
429
boolean hasMethod = Reflections.methodExists(clazz, "validate");
430
431
// Get property name from getter
432
Method getter = Reflections.findDeclaredMethod(clazz, "getName");
433
String propertyName = Reflections.getPropertyName(getter); // "name"
434
```
435
436
### Generic Type Resolution
437
438
```java
439
// Resolve collection element types
440
Field listField = MyClass.class.getDeclaredField("stringList");
441
Type fieldType = listField.getGenericType();
442
Class<?> elementType = Types.getCollectionBaseType(List.class, fieldType);
443
444
// Resolve map types
445
Field mapField = MyClass.class.getDeclaredField("stringMap");
446
Type mapType = mapField.getGenericType();
447
Class<?> keyType = Types.getMapKeyType(mapType);
448
Class<?> valueType = Types.getMapValueType(mapType);
449
450
// Resolve type variables
451
class Container<T> {
452
List<T> items;
453
}
454
Type resolvedType = Types.resolveTypeVariables(Container.class, itemsFieldType);
455
```
456
457
### Annotation Processing
458
459
```java
460
// Get annotations with meta-annotations
461
Set<Annotation> annotations = new HashSet<>();
462
// ... populate annotations
463
464
Class<? extends Annotation> metaType = MyMetaAnnotation.class;
465
Set<Annotation> filtered = Reflections.getAnnotationsWithMetaAnnotation(annotations, metaType);
466
467
// Check if annotations are cacheable
468
boolean cacheable = Reflections.isCacheable(annotations);
469
```
470
471
### Class Loading and Type Checking
472
473
```java
474
// Load class with fallback loaders
475
ClassLoader[] loaders = {
476
Thread.currentThread().getContextClassLoader(),
477
MyClass.class.getClassLoader(),
478
ClassLoader.getSystemClassLoader()
479
};
480
481
Class<?> loadedClass = Reflections.classForName("com.example.MyClass", loaders);
482
483
// Type checking
484
Class<?> rawType = Types.getRawType(someGenericType);
485
boolean isArray = Reflections.isArrayType(String[].class);
486
boolean isParameterized = Reflections.isParameterizedType(List.class);
487
```
488
489
### Constructor Operations
490
491
```java
492
// Find and use constructors
493
Constructor<?> constructor = Reflections.findDeclaredConstructor(MyClass.class, String.class, int.class);
494
Reflections.setAccessible(constructor);
495
Object instance = constructor.newInstance("test", 42);
496
497
// Get all constructors
498
Set<Constructor<?>> constructors = Reflections.getAllDeclaredConstructors(MyClass.class);
499
```
500
501
### Interface Implementation Analysis
502
503
```java
504
// Check method compatibility
505
Method interfaceMethod = MyInterface.class.getDeclaredMethod("process", String.class);
506
Method implementationMethod = MyImplementation.class.getDeclaredMethod("process", String.class);
507
boolean compatible = Types.isCompatible(implementationMethod, interfaceMethod);
508
509
// Find implementing method
510
Method impl = Types.getImplementingMethod(MyImplementation.class, interfaceMethod);
511
512
// Get interface type parameters
513
Type[] typeArgs = Types.getActualTypeArgumentsOfAnInterface(
514
MyGenericImplementation.class,
515
MyGenericInterface.class
516
);
517
```
518
519
### Security-Aware Accessibility
520
521
```java
522
// Use privileged actions in security-managed environments
523
AccessibleObject member = somePrivateField;
524
525
// Set accessible with proper permissions
526
AccessController.doPrivileged(new SetAccessiblePrivilegedAction(member));
527
528
// Use the member
529
// ...
530
531
// Unset accessible when done
532
AccessController.doPrivileged(new UnSetAccessiblePrivilegedAction(member));
533
```
534
535
### Advanced Type Utilities
536
537
```java
538
// Type boxing and conversion
539
Type primitiveType = int.class;
540
Type boxedType = Types.boxedType(primitiveType); // Integer.class
541
Class<?> boxedClass = Types.boxedClass(int.class); // Integer.class
542
543
// Complex assignability checking
544
boolean assignable = Reflections.isAssignableFrom(
545
List.class, new Type[]{String.class},
546
ArrayList.class, new Type[]{String.class}
547
);
548
549
// Build type maps for analysis
550
Set<Type> types = Set.of(String.class, Integer.class, List.class);
551
Map<Class<?>, Type> typeMap = Reflections.buildTypeMap(types);
552
```
553
554
This reflection utilities package provides powerful capabilities for runtime type analysis, dynamic method invocation, and complex generic type resolution, essential for building flexible and dynamic Java applications.