3

Java コンパイラーが (ほぼ) 常にコンパイル時に静的メソッドを解決するのは一般的な事実です。例えば:

public class Super {
    static void someMethod() {
        // Do something...
    }
}
public class Derived extends Super {
    // Some other methods, excluding someMethod
}

テストコード:

Derived derived = new Derived();
derived.someMethod();

これは Super.someMethod() を呼び出す必要がありますよね? そして、javacが生成するように、コンパイル時に解決する必要がありますが、生成されることがわかりinvokestatic Super.someMethodましたinvokestatic Derived.someMethod。なぜそうしているのですか?そして、どういうわけかこの動作を変更する方法はありますか?

私が間違っている場合は、私を修正してください。

4

2 に答える 2

4

Superと の間に中間スーパークラスがあると仮定しましょうDerived(たとえば と呼ばれますIntermediate)。

コンパイラが生成する理由は、 の実装を挿入するためにDerived.someMethod再コンパイルする可能性があるためです。これにより、 からの実装がシャドウされます。IntermediatesomeMethodSuper

于 2013-08-11T12:01:39.143 に答える
1

記録のために:

public class TestSuperDerived {
    public static void main(String[] argv) {
        DerivedClass.someMethod();
    }
}
class SuperClass {
    static void someMethod() {
        System.out.println("Here!");
    }
}
class DerivedClass extends SuperClass {
    // Some other methods, excluding someMethod
}

javap 出力:

C:\JavaTools>javap -c TestSuperDerived
Compiled from "TestSuperDerived.java"
public class TestSuperDerived {
  public TestSuperDerived();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #2                  // Method DerivedClass.someMethod:()V
       3: return
}
于 2013-08-11T12:30:18.697 に答える