Javaでの静的割当てと動的割当て
2476 ワード
Javaマルチステートのいくつかの基本的な特徴で、割り当て呼び出しについて説明します.
最初は、一般的な方法で、例を導入し、次の例の出力を見てみましょう.
出力結果:
hello, guy! hello, guy!
そう、プログラムはおなじみのオーバーロード(Overload)で、出力結果も分かるはずですが、なぜ出力結果がこれなのでしょうか.
まず、次のコードの定義について説明します.
我々は
Humanを変数と呼ぶ
静的タイプ
Manを変数と呼ぶ
実際のタイプ.
ここで、変数の静的タイプと動的タイプはプログラム中で変化することができ、違いは変数の静的タイプがコンパイル段階で分かることであるが、動的タイプは実行期間で決定され、コンパイラはコンパイル時に変数の実際のクラスが何であるかを知らない(個人的には多態を実現するためにこのように設定される可能性があると考えられる).
コードに戻ると、メソッドの受信者がStaticDispatchのインスタンスsdであると決定したため、最終的に呼び出されるリロードバージョンは、受信パラメータのタイプに依存します.
実際、仮想マシン(コンパイラと呼ぶべき)は、リロード時にパラメータの静的タイプによって判定の根拠となり、静的タイプはコンパイル期間で分かるので、コンパイラはコンパイル段階で静的タイプに基づいてどのリロードバージョンを使用するかを判定することができる.そこで,例の2つのメソッドの呼び出しはいずれもHumanをパラメータとするバージョンである.
Javaでは,静的タイプでメソッド実行バージョンを位置決めするすべての割り当て動作を静的割り当てと呼ぶ.
動的配分を見ると、多態のもう一つの重要な体現と大きく関連しています.この体現は何なのか、皆さんも推測できるかもしれません.間違いなく、書き直しです.
例は次のとおりです.
出力結果:
hello man! hello women! hello women!
この結果はもう何も言うことはありませんが、仮想マシンはどのようにしてどの方法を呼び出すかを知っていますか?
実際にはman変数の実際のタイプを2回変更することで呼び出し関数のバージョンが異なり、仮想マシンが変数の実際のタイプに基づいて書き換え方法を呼び出していることがわかります.
例からも分かるように、変数の実際のタイプは実行期間によって決定され、書き換え方法の呼び出しも実際のタイプに基づいて呼び出される.
このような実行期間において実際のタイプに基づいてメソッド実行バージョンを決定する割り当て動作を動的割り当てと呼ぶ.
最初は、一般的な方法で、例を導入し、次の例の出力を見てみましょう.
/**
*
* @author Sel
*
* 2014.4.3
*/
public class StaticDispatch {
public void sayHello(Human guy) {
System.out.println("hello, guy!");
}
public void sayHello(Man guy) {
System.out.println("hello, man!");
}
public void sayHello(Women guy) {
System.out.println("hello, women!");
}
public static void main(String[] args) {
Human man = new Man();
Human women = new Women();
StaticDispatch sd = new StaticDispatch();
sd.sayHello(man);
sd.sayHello(women);
}
}
class Human {
}
class Man extends Human {
}
class Women extends Human {
}
出力結果:
hello, guy! hello, guy!
そう、プログラムはおなじみのオーバーロード(Overload)で、出力結果も分かるはずですが、なぜ出力結果がこれなのでしょうか.
まず、次のコードの定義について説明します.
Human man = new Man();
我々は
Humanを変数と呼ぶ
静的タイプ
Manを変数と呼ぶ
実際のタイプ.
ここで、変数の静的タイプと動的タイプはプログラム中で変化することができ、違いは変数の静的タイプがコンパイル段階で分かることであるが、動的タイプは実行期間で決定され、コンパイラはコンパイル時に変数の実際のクラスが何であるかを知らない(個人的には多態を実現するためにこのように設定される可能性があると考えられる).
コードに戻ると、メソッドの受信者がStaticDispatchのインスタンスsdであると決定したため、最終的に呼び出されるリロードバージョンは、受信パラメータのタイプに依存します.
実際、仮想マシン(コンパイラと呼ぶべき)は、リロード時にパラメータの静的タイプによって判定の根拠となり、静的タイプはコンパイル期間で分かるので、コンパイラはコンパイル段階で静的タイプに基づいてどのリロードバージョンを使用するかを判定することができる.そこで,例の2つのメソッドの呼び出しはいずれもHumanをパラメータとするバージョンである.
Javaでは,静的タイプでメソッド実行バージョンを位置決めするすべての割り当て動作を静的割り当てと呼ぶ.
動的配分を見ると、多態のもう一つの重要な体現と大きく関連しています.この体現は何なのか、皆さんも推測できるかもしれません.間違いなく、書き直しです.
例は次のとおりです.
/**
*
* @author Sel
*
* 2014.4.3
*/
public class DynamicDispatch {
public static void main(String[] args) {
Human man = new Man();
Human women = new Women();
man.sayHello();
women.sayHello();
man = new Women();
man.sayHello();
}
}
abstract class Human {
protected abstract void sayHello();
}
class Man extends Human {
@Override
protected void sayHello() {
System.out.println("hello man!");
}
}
class Women extends Human {
@Override
protected void sayHello() {
System.out.println("hello women!");
}
}
出力結果:
hello man! hello women! hello women!
この結果はもう何も言うことはありませんが、仮想マシンはどのようにしてどの方法を呼び出すかを知っていますか?
実際にはman変数の実際のタイプを2回変更することで呼び出し関数のバージョンが異なり、仮想マシンが変数の実際のタイプに基づいて書き換え方法を呼び出していることがわかります.
例からも分かるように、変数の実際のタイプは実行期間によって決定され、書き換え方法の呼び出しも実際のタイプに基づいて呼び出される.
このような実行期間において実際のタイプに基づいてメソッド実行バージョンを決定する割り当て動作を動的割り当てと呼ぶ.