4

次のコードスニペットは実行時になります。

class Vehicle {
    public void printSound() {
        System.out.print("vehicle");
    }
}

class Car extends Vehicle {
    public void printSound() {
        System.out.print("car");
    }
}

class Bike extends Vehicle {
    public void printSound() {
        System.out.print("bike");
    }
}

public class Test {
    public static void main(String[] args) {
        Vehicle v = new Car();
        Bike b = (Bike) v;

        v.printSound();
        b.printSound();
    }   
}

私の質問は、なぜそれが実行時エラーになるのにコンパイルエラーにはならないのかということです。コンパイラは、「v」がすでに「車」であり、「自転車」にキャストできないことを知っているべきではありませんか?

4

7 に答える 7

11

理論的には、コンパイラが自分自身に次のように言うことは可能です。 "vはローカル変数であり、に割り当てられますCar。キャストが試行される前のどの時点でBikeも、その値は変更されませCarん。正常にキャストされましたBike。したがって、これはエラーです。」

ただし、その分析を行うJavaコンパイラはありません。それは本当に最も単純な場合にのみ価値があります。代わりに、コンパイラーがキャストを認識し、をにキャストできるという理由で、それを許可するという動作VehicleBike行われます。

一般に、それはキャストが意味することです。それは、この割り当てが失敗する可能性があるとしても、失敗しないことをかなり確信していることをコンパイラーに伝えます。コードのコンパイルを許可する代わりに、実行時例外のリスクを想定します。

于 2012-04-30T17:53:30.200 に答える
5

スーパークラスからのキャストは機能する可能性があるため、許可されます(コンパイル中)。まったく異なるクラスからのキャストは許可されていません。例:

Integer a = 1;
String b = (String)a; // compile error
String b = (String)(Object)a; // runtime error
于 2012-04-30T17:50:34.617 に答える
4

にとって

R r = /* some code to initialize "r" */
T t = (T) r;

Java言語仕様によると:

Rが通常のクラス(配列クラスではない)の場合:

  • Tがクラス型の場合、RはTと同じクラスまたはTのサブクラスである必要があります。そうでない場合、実行時例外がスローされます。
  • Tがインターフェイスタイプの場合、RはインターフェイスTを実装する必要があります。そうしないと、ランタイム例外がスローされます。
  • Tが配列型の場合、実行時例外がスローされます。
于 2012-04-30T17:54:07.870 に答える
1

オブジェクトの型キャストは実行時に行われるため、コンパイラはそれを認識しません

于 2012-04-30T17:50:07.153 に答える
0

いいえ。vはaVehicleであり、にキャストできる可能性がありますBike。すべてのオブジェクトの実際のランタイムタイプを把握するのはコンパイラの仕事ではありません(特にそれが不可能な場合があるため)。

于 2012-04-30T17:48:37.993 に答える
0

Javaのセマンティクスでは、これにより実行時エラーが発生する必要があるとされています。この場合、コードを見て、実行時に間違いなくエラーがスローされることを確認することは可能ですが、コンパイラーは、aが目的のものでClassCastExceptionはないことをどのように認識しますか?

IntelliJやEclipseのような編集者は、これらの種類のエラーに気づき、警告することができます(そして実際にそうします)が、Javaの規則では、これはコンパイルする必要のある正当なコードであるとされています。

于 2012-04-30T17:52:04.817 に答える
0

v変数をすでに定義しているため、これは実行時エラーですCarCarに変換することはできませんBike

コンパイラーは一般にセマンティクスをチェックしないため、コンパイラーはこの種の値の割り当てをチェックしません。

于 2012-04-30T17:54:37.267 に答える