3

HashMapいくつかのクラスがフィールドから計算されたハッシュコードを持つ集中型 Java プログラムがありfinalます。例えば:

public class Foo {
    private final int bar;
    private final String zot;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + bar;
        result = prime * result + zot.hashCode();
        return result;
    }
}

コンパイラは、オブジェクトの初期化後にハッシュコードが変更できないことを確認し、それを追加private finalフィールドに事前計算することができます。Oracle JDK 7 のような現在の Java コンパイラはこれを行いますか? ファイルを逆アセンブルすることはでき.classますが、JIT は実行時にこの種の最適化も行う可能性があり、そこには表示されません。とにかく、これ以外のケースにも興味があるので、コンパイラが自動的に行う最適化を特定するための一般的なアプローチを見つけることは素晴らしいことです.

4

3 に答える 3

6

Oracle JDK 7 のような現在の Java コンパイラはこれを行いますか?

javacほとんど最適化を行いません。

.class ファイルを逆アセンブルできました。

最適化の観点から見たものが気に入らないかもしれません。;)

しかし、JITは実行時にこの種の最適化も行う可能性があり、そこには表示されません。

JIT がこれを最適化した場合、それは表示されず、実際にはこれは行われません。これが、String が実行時にコード内で明示的に hashCode() をキャッシュする理由です。

于 2013-09-27T01:58:13.467 に答える
2

いいえ、コンパイラはこれを行いません。ただし、ハッシュコードを自分でフィールドに格納し、常に新たに計算する代わりにそれを参照することは難しくありません。

private int hash = -1;

public int hashCode() {
    if (hash == -1) {
        // compute hash, assign it to the hash variable, and return it
    } else {
        return hash;
    }
}

このアプローチは実際にはクラスによって採用されており、そのソースStringを調べればわかります。

121  /** Cache the hash code for the string */
122  private int hash; // Default to 0
于 2013-09-27T01:56:57.547 に答える
1

コンパイラが適切なメソッドに対してそれを行うことは可能ですが、そうhashCode(),ではありません。javap -p追加されたフィールドがあるかどうかで自分の目で確認でき、 javap -c.

ただし、投稿した方法は適切な候補ではありません。実行時の実装はString.hashCode()、コンパイラで使用できるものとは異なる場合があります。コンパイラは、そうではないと想定できません。

于 2013-09-27T02:07:15.027 に答える