18
18
19
19
package com .railwayteam .railways .util ;
20
20
21
+ import com .google .common .cache .Cache ;
22
+ import com .google .common .cache .CacheBuilder ;
23
+ import org .jetbrains .annotations .Nullable ;
24
+
21
25
import java .lang .invoke .MethodHandles ;
26
+ import java .lang .invoke .VarHandle ;
27
+ import java .util .concurrent .ExecutionException ;
22
28
23
29
@ SuppressWarnings ("unchecked" )
24
30
public class MethodVarHandleUtils {
31
+ private static final Cache <VarHandleInfo , VarHandle > varHandleCache = CacheBuilder .newBuilder ().build ();
32
+
25
33
private static final MethodHandles .Lookup lookup = MethodHandles .lookup ();
26
-
34
+
27
35
public static <T > T getStaticField (Class <?> clazz , String fieldName , Class <T > type ) throws NoSuchFieldException , IllegalAccessException {
28
- return (T ) lookup .findStaticVarHandle (clazz , fieldName , type ).get ();
36
+ T value = null ;
37
+
38
+ try {
39
+ value = (T ) varHandleCache .get (
40
+ new VarHandleInfo (clazz , fieldName , type ),
41
+ () -> lookup .findStaticVarHandle (clazz , fieldName , type )
42
+ ).get ();
43
+ } catch (ExecutionException ignored ) {}
44
+
45
+ return value ;
29
46
}
30
47
31
48
public static <T > T getStaticField (Class <?> clazz , String fieldName , Class <T > type , T defaultValue ) {
32
49
T returnValue = defaultValue ;
33
-
50
+
34
51
try {
35
52
returnValue = getStaticField (clazz , fieldName , type );
36
53
} catch (NoSuchFieldException | IllegalAccessException ignored ) {}
37
-
54
+
38
55
return returnValue ;
39
56
}
57
+
58
+ public static <T , U > T getPrivateField (U instance , Class <U > clazz , String fieldName , Class <T > type , T defaultValue ) {
59
+ T returnValue = defaultValue ;
60
+
61
+ VarHandle handle = findPrivateFieldVarHandle (new VarHandleInfo (clazz , fieldName , type ));
62
+ if (handle != null ) {
63
+ returnValue = (T ) handle .get (instance );
64
+ }
65
+
66
+ return returnValue ;
67
+ }
68
+
69
+ @ Nullable
70
+ public static VarHandle findPrivateFieldVarHandle (VarHandleInfo info ) {
71
+ try {
72
+ return varHandleCache .get (info , () -> {
73
+ MethodHandles .Lookup privateLookup = MethodHandles .privateLookupIn (info .clazz (), lookup );
74
+ return privateLookup .findVarHandle (info .clazz (), info .fieldName (), info .type ());
75
+ });
76
+ } catch (ExecutionException ignored ) {
77
+ return null ;
78
+ }
79
+ }
80
+
81
+ public record VarHandleInfo (Class <?> clazz , String fieldName , Class <?> type ) {
82
+ }
40
83
}
0 commit comments