如何解决li_lazy_init_update_static



我正在尝试在上游库中的非公共方法初始化 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错误检测器报告说ofMethod()有一个li_lazy_init_update_static问题。

我明白这在说什么。我看到这两个步骤(可以分配和设置可访问(在多线程环境中是有问题的。

如何解决问题?我应该使用双检查锁定吗?

或我应该将ofMethod()逻辑放入ofHandle()

我正在回答我自己的问题。

持有懒惰对象参考的想法是一个坏主意。

即使有双重检查的锁定,

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;
}

任何人都可以更改accessible状态。

我最终得到了以下代码,这不取决于任何外部变量。

static Method ofMethod() {
    try {
        final Method ofMethod = ...;
        if (!ofMethod.isAccessible()) {
            ofMethod.setAccessible(true);
        }
        return ofMethod;
    } catch (final NoSuchMethodException nsme) {
        throw new RuntimeException(nsme);
    }
}

相关内容

  • 没有找到相关文章

最新更新