|
8 | 8 | import java.lang.annotation.Annotation; |
9 | 9 | import java.lang.reflect.Constructor; |
10 | 10 | import java.lang.reflect.Field; |
11 | | -import java.lang.reflect.RecordComponent; |
| 11 | +import java.lang.reflect.Method; |
12 | 12 | import java.util.ArrayList; |
13 | 13 | import java.util.Collection; |
14 | 14 | import java.util.List; |
@@ -36,31 +36,43 @@ public static <T> T newInstanceOf(Class<T> type) { |
36 | 36 |
|
37 | 37 | /** |
38 | 38 | * Creates an instance of a record class using its canonical constructor with provided values. |
| 39 | + * This method uses reflection to maintain compatibility with Java 11 while supporting records on Java 17+. |
39 | 40 | * |
40 | 41 | * @param <T> the type of the record |
41 | 42 | * @param type the record class |
42 | 43 | * @param recordValues a map of field names to their values |
43 | 44 | * @return a new instance of the record |
44 | 45 | */ |
45 | 46 | public static <T> T newRecordInstance(Class<T> type, Map<String, Object> recordValues) { |
46 | | - if (!type.isRecord()) { |
| 47 | + if (!isRecord(type)) { |
47 | 48 | throw new PoijiInstantiationException("Type " + type.getName() + " is not a record", |
48 | 49 | new IllegalArgumentException("Expected a record type")); |
49 | 50 | } |
50 | 51 |
|
51 | 52 | try { |
52 | | - RecordComponent[] components = type.getRecordComponents(); |
| 53 | + // Use reflection to call getRecordComponents() to maintain Java 11 compatibility |
| 54 | + Method getRecordComponentsMethod = Class.class.getMethod("getRecordComponents"); |
| 55 | + Object[] components = (Object[]) getRecordComponentsMethod.invoke(type); |
| 56 | + |
53 | 57 | Class<?>[] parameterTypes = new Class<?>[components.length]; |
54 | 58 | Object[] args = new Object[components.length]; |
55 | 59 |
|
| 60 | + // Get methods from RecordComponent class using reflection |
| 61 | + Class<?> recordComponentClass = Class.forName("java.lang.reflect.RecordComponent"); |
| 62 | + Method getNameMethod = recordComponentClass.getMethod("getName"); |
| 63 | + Method getTypeMethod = recordComponentClass.getMethod("getType"); |
| 64 | + |
56 | 65 | for (int i = 0; i < components.length; i++) { |
57 | | - RecordComponent component = components[i]; |
58 | | - parameterTypes[i] = component.getType(); |
59 | | - Object value = recordValues.get(component.getName()); |
| 66 | + Object component = components[i]; |
| 67 | + String componentName = (String) getNameMethod.invoke(component); |
| 68 | + Class<?> componentType = (Class<?>) getTypeMethod.invoke(component); |
| 69 | + |
| 70 | + parameterTypes[i] = componentType; |
| 71 | + Object value = recordValues.get(componentName); |
60 | 72 |
|
61 | 73 | // If value is null, use default values for primitives |
62 | | - if (value == null && component.getType().isPrimitive()) { |
63 | | - value = getDefaultValue(component.getType()); |
| 74 | + if (value == null && componentType.isPrimitive()) { |
| 75 | + value = getDefaultValue(componentType); |
64 | 76 | } |
65 | 77 |
|
66 | 78 | args[i] = value; |
@@ -101,13 +113,24 @@ private static Object getDefaultValue(Class<?> type) { |
101 | 113 | } |
102 | 114 |
|
103 | 115 | /** |
104 | | - * Checks if a class is a record. |
| 116 | + * Checks if a class is a record using reflection to maintain Java 11 compatibility. |
| 117 | + * Records are only available in Java 16+, so this method will return false on earlier versions. |
105 | 118 | * |
106 | 119 | * @param type the class to check |
107 | 120 | * @return true if the class is a record, false otherwise |
108 | 121 | */ |
109 | 122 | public static boolean isRecord(Class<?> type) { |
110 | | - return type.isRecord(); |
| 123 | + try { |
| 124 | + // Use reflection to call isRecord() method to maintain Java 11 compatibility |
| 125 | + Method isRecordMethod = Class.class.getMethod("isRecord"); |
| 126 | + return (Boolean) isRecordMethod.invoke(type); |
| 127 | + } catch (NoSuchMethodException e) { |
| 128 | + // isRecord() method doesn't exist, we're running on Java < 16 |
| 129 | + return false; |
| 130 | + } catch (Exception e) { |
| 131 | + // Some other error occurred |
| 132 | + return false; |
| 133 | + } |
111 | 134 | } |
112 | 135 |
|
113 | 136 | /** |
|
0 commit comments