是否有警卫来检查Java是否调用了一个方法?

ski*_*iwi 3 java optimization performance

请考虑以下代码:

public class BasicBuildOrder {
    private List<GameObject> gameObjects = new ArrayList<>();

    private List<GameObject> savedState;

    public void saveState() {
        savedState = new ArrayList<>(gameObjects);
    }

    public void resetToSavedState() {
        if (savedState == null) {
            throw new IllegalStateException("the state has not been saved");
        }
        gameObjects = savedState;
    }

    public void add(GameObject gameObject) {
        gameObjects.add(gameObject);
    }

    public void get(int index) {
        return gameObjects.get(index);
    }

    public void remove(GameObject gameObject) {
        gameObjects.remove(gameObject);
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在实现一种模式,您可以将列表标记为在某个特定状态下保存,然后恢复该状态.我知道当前的保存/重置方式有点阴暗并且提供O(n)性能,而这可以通过标记已添加,检索和删除哪些项来改进.

现在我看到一个问题是在调用之前resetToSavedState()会调用,因此我需要检查它.saveState()

我的问题是:if (savedState == null)如果知道saveState()已经调用了,那么在某些时候检查是否被Java(由编译器或在运行时)优化掉了,因此savedState不能再进行检查null了?

另外一个问题,是否有一种模式可用于此方法A-called-before-methodB关系?

Tag*_*eev 5

将Java源代码编译为.class文件时无法进行优化.它可以在运行时通过JIT编译器优化如果两个saveState()resetToSavedState()由相同方法调用,并且两者都在JIT编译期间内联有(或一些更深呼叫链被完全内联).内联是很有可能这里saveState()resetToSavedState()非常简单.之后,两者都成为外部方法的一部分,在构建控制流图和值分析之后,可以确定没有控制路径进入if语句,因此将修剪这样的CFG边缘.但是你不应该依赖于这种情况.

通常,只能查看程序代码(不实际执行它),您无法可靠地预测程序顺序.但是,额外的空检查在性能方面几乎没有任何意义,因此您不必担心它.