3

まず、宣言された型の意味を明確にしましょう。SuperBoss がクラス Boss のスーパークラスであるとします。

SuperBoss mrBond = new Boss();

SuperBoss は宣言された型で、Boss は実際の型です。

個人的には、次の実行時例外により、宣言された型が実行時に変更されると思います。

SuperBoss mrWayne = new SuperBoss();
((Boss)mrWayne).randomMethod(); 

//Exception: java.lang.ClassCastException: SuperBoss cannot be cast to Boss

これは些細なことに思えるかもしれませんが、私は次の四半期に家庭教師をする予定であり、学生に間違ったことを教えたくありません. そして、私の教授と彼女の助手は、この四半期について互いに同意しませんでした. 私の教授は、キャストによって、単一のステートメントの実行時に宣言された型が実際に完全に変更されると考えています。TA は、実行時にキャストがチェックされるだけで、実際には宣言された型を変更しないと強く信じていました。

4

2 に答える 2

3

私の教授は、キャストによって、単一のステートメントの実行時に宣言された型が実際に完全に変更されると考えています。TA は、実行時にキャストがチェックされるだけで、実際には宣言された型を変更しないと強く信じていました。

実際、ある意味ではどちらも正しいと思います。彼らが言っていることに矛盾はありません...彼らが実際に言っていることを理解できれば.

の宣言された型はmrWayne変更されません。の宣言された型((Boss) mrWayne)は「変更」されます。または少なくとも、 の宣言された型とは異なりmrWayneます。

ここでの本当の問題は、誰かがずさんな用語を使用しているということです...そして、人々はお互いを通り過ぎて話しています.


この例を考えてみましょう:

public class Test {
   public static void method(Object t) {
       system.out.println("Its an object");
   }
   public static void method(Test t) {
       system.out.println("Its a test");
   }
   public static void main(String[] args) {
       Test t = new Test();
       method(t);
       method((Object) t);
   }
}

これにより、次のように出力されます。

Its a test
Its an object

なんで?の宣言された(Object) tObject... ではないためTestです。また、特定の呼び出しに の 2 つのオーバーロードのどちらが使用されるかを決定するのは、宣言された型 (実行時の型ではない) です。method

見る?

それはすべて、あなたが話している内容に依存します。宣言された変数の型、または宣言された式の型。

于 2013-06-15T06:07:34.223 に答える
1

「宣言された」型は、コンパイラに宣言したものです。プログラムのコンパイル後は変更されません。

「ランタイム」型は、変数に割り当てられる実際のオブジェクトの型です。新しいオブジェクトを割り当てたときにのみ変更されます。(特定のオブジェクトに対して変更されることはありません。オブジェクト インスタンスはそのクラスを変更できません)。

キャストは 2 つの橋渡しをします。つまり、実行時の型をチェックし、その型を宣言できるようにします。チェックが失敗した場合、プログラムは (RuntimeException で) 中止されます。コンパイラよりも多くの型情報がある場合は、これを行う必要があります。次に、問題のオブジェクトが単なる「SuperBoss」ではなく、実際に「Boss」であることをコンパイラーに「宣言」できます (これは、コンパイラーが他の方法で保証できる最高のものです)。

私の教授は、キャストによって、単一のステートメントの実行時に宣言された型が実際に完全に変更されると考えています。

キャストは、コンパイル時により具体的な型を「宣言」します。ただし、これを安全にするための実行時チェックも含まれています。

TA は、実行時にキャストがチェックされるだけで、実際には宣言された型を変更しないと強く信じていました。

チェックは実行時に行われますが、コードにキャストを含めることで、コンパイル時により具体的な型宣言を行うことができます。

((Boss)mrWayne).randomMethod(); 

次の 2 つのことが起こります。

  • コンパイル時: これがボスであることを宣言します。そうしないと、メソッドを呼び出すことができませんでした。

  • 実行時: JVM は、そのオブジェクトが本当に Boss であるかどうかをチェックします。

于 2013-06-15T06:08:37.337 に答える