2012-04-30 7 views
2
次のコードスニペットは、実行時になります

のJava鋳造

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'がすでに '車'であり、 'バイク'にキャストできないことを知ってはいけませんか?

答えて

9

は、それは可能でしょう:「vはローカル変数である、それはCarように割り当てられていない時点でBikeしようとしたキャストする前には、それがその値を変更しないと、 CarBikeに正常にキャストする方法がないため、これはエラーです。

しかし、私はあなたのためにその分析を行うJavaコンパイラは分かりません。最も単純なケースでは本当に価値があるだけです。その代わりに、コンパイラはキャストを見て、VehicleBikeにキャストすることが可能であるという理由から、そのように動作します。

一般的に、これはキャストの意味です。コンパイラに、この割り当てが失敗する可能性があるにもかかわらず、そうしないと確信しています。コードをコンパイルするのと引き換えに、実行時例外が発生する危険性があります。

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

Java言語仕様について

0

番号vVehicleであり、Bikeにキャストすることができます。すべてのオブジェクトの実際のランタイムタイプを把握するのはコンパイラの仕事ではありません(特に不可能な場合があるため)。コンパイラが動作する可能性があり、スーパークラスからキャスト

1

型キャストは、実行時に発生するので、(コンパイル時に)許可されています。

Integer a = 1; 
String b = (String)a; // compile error 
String b = (String)(Object)a; // runtime error 
4

を認識doen'tように、オブジェクトの

0

Javaのセマンティクスでは、実行時エラーが発生する必要があると言われています。この場合、コードを見て、実行時に間違いなくエラーをスローすることがありますが、コンパイラはClassCastExceptionがあなたが望むものではないことをどのように知っていますか?

IntelliJとEclipseのような編集者は、この種のエラーに気づいて警告することができますが、Javaの規則ではコンパイルが必要な正当なコードだと言われています。 。コンパイラは自分自身に言うの理論的には

2

は言う:

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

  • RはTと同じクラスかTのサブクラスのいずれかでなければならないか、実行時例外がスローされます。
  • Tがインターフェイスの種類である場合、RはインターフェイスTを実装する必要があります。または、実行時例外がスローされます。
  • Tが配列型の場合は、実行時例外がスローされます。
+0

ニースと簡単な説明。今後のJLS SE8への直接参照用https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html – georger

0

すでにCarとして変数vを定義したので、これはランタイムエラーです。 CarBikeに変換することはできません。

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