Java,リロードトラップ,静的割当て,書き換え,動的割当て.

2563 ワード

本明細書で説明する内容は、問題:リロードされたトラップ、静的割り当て、書き換え、動的割り当て
public class StaticDispatch {
    static abstract class Human{}
    static class Man extends Human{}
    static class Woman extends Human{}

    public void sayHello(Human guy){
        System.out.println("hello,guy!");
    }
    public void sayHello(Man guy){
        System.out.println("hello,gentleman!");
    }
    public void sayHello(Woman guy){
        System.out.println("hello,lady!");
    }

    public static void main(String[] args){
        Human man=new Man();
        Human woman=new Woman();

        StaticDispatch sr=new StaticDispatch();

        sr.sayHello(man);
        sr.sayHello(woman);
    }
}

//print:
//hello,guy!
//hello,guy!

コードを見たばかりの頃は、結果がhello,gentleman( )hello,lady!になると思っていたのですが、なぜパラメータがHumanのリロード方法を選んだのでしょうか?要点は以下の通りです.
  • Human man=new Man()において、Humanは静的タイプまたは外観タイプと呼ばれ、Manは実際のタイプと呼ばれている.
  • コンパイラはプログラムをコンパイルするときに1つのオブジェクトの実際のタイプが何なのか分からず、実行期間でしか確定できない.静的タイプはコンパイラで知られています.
  • 上記のコードでは、2つの静的タイプが同じであるが実際のタイプが異なる変数を定義することができるが、仮想マシン(またはコンパイラ)は、再ロード時に実際のタイプではなくパラメータの静的タイプによって判定の根拠となる.
  • したがって、コンパイルフェーズでは、Javacコンパイラがパラメータの静的タイプに基づいてどのリロードバージョンを使用するかを決定するので、呼び出し先としてsayHello(Human)を選択した.
  • 静的タイプに依存してメソッド実行バージョンを特定するすべての割り当て動作を静的割り当てと呼び、静的割り当ての典型的な応用はメソッドの再ロードである.

  • 結論:どのメソッドがオブジェクトの静的タイプを通過するかを決定します.
    上記では、静的ディスパッチについて説明し、動的ディスパッチについて説明します.
    動的割り当てと書き換えには密接な関連があります.
    public class Main {
        public static void main(String args[]) {
            Human man=new Man();
            Human woman=new Woman();
    
            man.sayHello();
            woman.sayHello();
    
            man=new Woman();
            man.sayHello();
        }
        static abstract class Human{
            protected abstract void sayHello();
        }
        static class  Man extends Human{
            @Override
            protected void sayHello() {
                System.out.println("man say hello");
            }
        }
        static class Woman extends Human{
            @Override
            protected void sayHello() {
                System.out.println("woman say hello");
            }
        }
    }
    /*
      :
    man say hello
    woman say hello
    woman say hello
     */
    

    この印刷結果は懸念されず当然です.明らかに、ここで異なる結果が印刷されるのは、オブジェクトの実際のタイプが異なるためです.具体的な分析と解釈は私自身もよく分からないので、「java仮想マシンを深く理解する」P 253の内容を直接見ることをお勧めします.
    結論:書き換えメソッドの呼び出しは,実行期間に基づいて決定されたオブジェクトの実際のタイプに基づいて,どのメソッドを具体的に呼び出すかを決定する.
    まとめ:実際の開発では,メソッドのリロードであることに注意し,オブジェクトの静的タイプに応じてどのメソッドをリロードするかを選択し,メソッドの書き換えは通常と変わらない.