|
13 | 13 | import java.util.Arrays; |
14 | 14 | import java.util.Map; |
15 | 15 | import java.util.concurrent.ConcurrentHashMap; |
| 16 | +import java.util.function.Supplier; |
16 | 17 |
|
17 | 18 | public final class ClassAccess { |
18 | 19 |
|
@@ -105,38 +106,57 @@ public static <S, T> FieldAccess<S, T> field(Class<S> source, String name) throw |
105 | 106 | } |
106 | 107 |
|
107 | 108 | private static <S, T> FieldAccess<S, T> fieldAccess(FieldAccessKey<S> key) throws NoSuchFieldException { |
108 | | - FieldAccess<?, ?> fieldAccess = fieldCache.get(key); |
109 | | - if (fieldAccess == null) { |
| 109 | + //noinspection unchecked |
| 110 | + FieldAccess<S, T> fieldAccess = (FieldAccess<S, T>) fieldCache.get(key); |
| 111 | + if (fieldAccess != null) |
| 112 | + return fieldAccess; |
| 113 | + |
| 114 | + synchronized (fieldCache) { |
| 115 | + //noinspection unchecked |
| 116 | + fieldAccess = (FieldAccess<S, T>) fieldCache.get(key); |
| 117 | + if (fieldAccess != null) |
| 118 | + return fieldAccess; |
| 119 | + |
110 | 120 | Class<?> generated = defineHiddenIn(key.source(), generateFieldAccess(key)); |
111 | 121 | try { |
112 | | - fieldAccess = (FieldAccess<?, ?>) generated.getDeclaredConstructor().newInstance(); |
| 122 | + //noinspection unchecked |
| 123 | + fieldAccess = (FieldAccess<S, T>) generated.getDeclaredConstructor().newInstance(); |
113 | 124 | fieldCache.put(key, fieldAccess); |
114 | 125 | } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { |
115 | 126 | throw new RuntimeException(e); // Should not happen |
116 | 127 | } |
117 | 128 | } |
118 | | - //noinspection unchecked |
119 | | - return (FieldAccess<S, T>) fieldAccess; |
120 | 129 |
|
| 130 | + return fieldAccess; |
121 | 131 | } |
122 | 132 |
|
123 | 133 | public static <S, T> MethodAccess<S, T> method(Class<S> source, String name, Class<?>... parameters) throws NoSuchMethodException { |
124 | 134 | return methodAccess(new MethodAccessKey<>(source, name, parameters)); |
125 | 135 | } |
126 | 136 |
|
127 | 137 | private static <S, T> MethodAccess<S, T> methodAccess(MethodAccessKey<S> key) throws NoSuchMethodException { |
128 | | - MethodAccess<?, ?> methodAccess = methodCache.get(key); |
129 | | - if (methodAccess == null) { |
| 138 | + //noinspection unchecked |
| 139 | + MethodAccess<S, T> methodAccess = (MethodAccess<S, T>) methodCache.get(key); |
| 140 | + if (methodAccess != null) |
| 141 | + return methodAccess; |
| 142 | + |
| 143 | + synchronized (methodCache) { |
| 144 | + //noinspection unchecked |
| 145 | + methodAccess = (MethodAccess<S, T>) methodCache.get(key); |
| 146 | + if (methodAccess != null) |
| 147 | + return methodAccess; |
| 148 | + |
130 | 149 | Class<?> generated = defineHiddenIn(key.source(), generateMethodAccess(key)); |
131 | 150 | try { |
132 | | - methodAccess = (MethodAccess<?, ?>) generated.getDeclaredConstructor().newInstance(); |
| 151 | + //noinspection unchecked |
| 152 | + methodAccess = (MethodAccess<S, T>) generated.getDeclaredConstructor().newInstance(); |
133 | 153 | methodCache.put(key, methodAccess); |
134 | 154 | } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { |
135 | 155 | throw new RuntimeException(e); // Should not happen |
136 | 156 | } |
137 | 157 | } |
138 | | - //noinspection unchecked |
139 | | - return (MethodAccess<S, T>) methodAccess; |
| 158 | + |
| 159 | + return methodAccess; |
140 | 160 | } |
141 | 161 |
|
142 | 162 | private static Class<?> defineHiddenIn(Class<?> host, byte[] bytes) { |
|
0 commit comments