使用局部变量来保存全局变量的目的是什么?

时间:2014-06-13 14:02:54

标签: java string global-variables local-variables

我查看了String.hashcode()方法的源代码。这是6-b14中的实施,已经改变了。

public int hashCode() {
        int h = hash;
        if (h == 0) {
            int off = offset;
            char val[] = value;
            int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
}

我的问题是关于这一行:

int len = count;

其中count是表示字符串字符数的全局变量。

为什么局部变量len在这里用于循环条件而不是全局变量本身?因为没有操纵变量,只能阅读。如果使用全局字段来读取或写入本地变量,那么使用局部变量是一种好习惯吗?如果答案是肯定的,为什么还要阅读?

3 个答案:

答案 0 :(得分:2)

访问本地变量比实例变量快。此外,新的Java 8 Code(请参阅Anubians的答案)也考虑到了这一点。这就是为什么他们使用局部变量h进行哈希计算而不直接访问实例变量this.hash并创建本地指针char val[] = value;的原因。但考虑到这一点,我不知道他们为什么不在{for循环中使用i < val.length;甚至更好z = val.length; i < z;i < value.length;

答案 1 :(得分:2)

在String类中找到了一个关于String.trim()方法读取"avoid getfield opcode"的局部变量奇怪赋值的注释。

public String trim() {
    int len = value.length;
    int st = 0;
    char[] val = value;    /* avoid getfield opcode */

    while ((st < len) && (val[st] <= ' ')) {
        st++;
    }
    while ((st < len) && (val[len - 1] <= ' ')) {
        len--;
    }
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}

所以整个事情似乎与性能有关,正如Frank Olschewski指出的那样。

在Java字节码中,实例变量实际上由对象和名称引用(使用GETFIELD指令)。如果没有优化,VM必须做更多工作才能访问变量。

然后,代码的潜在性能损失是它在每次循环中使用相对昂贵的GETFIELD指令。该方法中的局部赋值在每次循环时都不需要GETFIELD

JIT优化器可能会优化循环,但也可能没有,因此开发人员可能会采取安全路径手动强制执行。

Avoiding getfield opcode上有一个单独的问题,其中包含详细信息。

答案 2 :(得分:1)

如果可以修改count,那么您需要一个局部变量。如果你正在进行多线程处理,那么你需要一个局部变量。创建局部变量是最安全的。但是,这并不是严格的必要条件。

在这种情况下,它太过分了,因为Strings无论如何都是不可变的。伯爵的价值甚至无法改变。

这几乎没用,这就是为什么在Java 8中它看起来像这样:

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

他们甚至不再计算,他们正在使用value.length,其中value是最终的char数组。

他们正在做char val[] = value,但这只是一个参考,绝对是不必要的。

通过使用局部变量可能会有一些微妙的微增强,或者它可能是为了可读性而做的,但它不是必需的(在我看来不太可读)。