我正在尝试为上游库中的非公共(public)方法初始化 MethodHandle
。
private static Method OF_METHOD;
static Method ofMethod() {
if (OF_METHOD == null) {
try {
OF_METHOD = RequestObject.class.getDeclaredMethod(
"of", Class.class, String.class, String.class,
Object.class, Object.class);
if (!OF_METHOD.isAccessible()) {
OF_METHOD.setAccessible(true);
}
} catch (final NoSuchMethodException nsme) {
throw new RuntimeException(nsme);
}
}
return OF_METHOD;
}
private static MethodHandle OF_HANDLE;
static MethodHandle ofHandle() {
if (OF_HANDLE == null) {
try {
OF_HANDLE = MethodHandles.lookup().unreflect(ofMethod());
} catch (final ReflectiveOperationException roe) {
throw new RuntimeException(roe);
}
}
return OF_HANDLE;
}
还有我的SpotBugs Bug Detecter 报告显示 ofMethod()
有一个 LI_LAZY_INIT_UPDATE_STATIC问题。
我明白它在说什么。我发现这两个步骤(分配和设置可访问)在多线程环境中是有问题的。
如何解决这个问题?我应该申请Double-checked locking ?
或者我应该将 ofMethod()
逻辑放入 ofHandle()
中?
最佳答案
我正在回答我自己的问题。
持有惰性对象引用的想法是一个坏主意。
即使有 Double-checked locking ,
private static volatile Method OF_METHOD;
static Method ofMethod() {
Method ofMethod = OF_METHOD;
if (ofMethod == null) {
synchronized (JacksonRequest.class) {
ofMethod = OF_METHOD;
if (ofMethod == null) {
try {
ofMethod = ...;
} catch (final NoSuchMethodException nsme) {
throw new RuntimeException(nsme);
}
if (!ofMethod.isAccessible()) {
ofMethod.setAccessible(true);
}
OF_METHOD = ofMethod;
}
}
}
return ofMethod;
}
任何人都可以更改可访问
状态。
我最终得到了以下不依赖于任何外部变量的代码。
static Method ofMethod() {
try {
final Method ofMethod = ...;
if (!ofMethod.isAccessible()) {
ofMethod.setAccessible(true);
}
return ofMethod;
} catch (final NoSuchMethodException nsme) {
throw new RuntimeException(nsme);
}
}
关于java - 如何解决 LI_LAZY_INIT_UPDATE_STATIC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56879515/