15

OCA Java SE 7 Programmer I 試験の勉強をしているので、初心者の質問です。よくわからない質問例があります。次のコードはコンパイルされますが、実行時に ClassCastException が発生します。

interface Roamable {
}

class Phone {
}

public class Tablet extends Phone implements Roamable {
    public static void main(String... args) {
        Roamable var = (Roamable) new Phone();
    }
}

に変更Roamable var = (Roamable) new Phone();するRoamable var = (Roamable) new String();と、すぐにコンパイル エラーが発生します。

2 つの質問:

  1. 上記のコードがコンパイルされるのはなぜですか? 電話は Roamable と無関係に思えますか?
  2. new Phone()コードが でコンパイルされるのに、 でコンパイルされないのはなぜnew String()ですか?
4

6 に答える 6

13

上記のコードがコンパイルされるのはなぜですか? 電話は Roamable と無関係に思えますか?

はいRoamable、インターフェイスであるため、ランタイム例外が発生する可能性がありますが、コンパイル時例外は発生しPhoneません。RoamablePhone

Java言語仕様ですでに定義されています。ここで私の答えをチェックしてください

コードが new Phone() でコンパイルされるのに、new String() でコンパイルされないのはなぜですか?

パッケージのようにclass String宣言されているためです。セクションで指定されているとおり: として宣言されたクラスは拡張できないため、サブクラスはありません。したがって、コンパイラは拡張できないことをすでに認識しています。したがって、インターフェースを実装するためのサブクラスの存在は不可能です。public final classjava.langjls 8.1.1.2 final classfinalString Roamable

編集:(以下のコメントへの返信付き)

それがインターフェースを実装するBサブクラスであると仮定しましょう。AT

今ステートメント:

   T t = (T)new A();

基本的には次と同じです:

   A aObj = new A() ;
   T t = (T)aObj ; // a run-time exception happen

結論に入る前に、 のオブジェクトで同じことをしましょうB:

   A aObj = new B();
   T t = (T)aObj; // no exception happen.

したがって、ここでスーパークラスとサブクラスを使用する本当の理由は参照です。このaObj2 番目のコード例のクラスも class のインスタンスですが、実装されているAclass のインスタンスでもあります。BT

于 2013-11-10T21:39:39.677 に答える
0

最初に、Java による明示的および暗黙的な型キャストについて読んでください。

そのユーザーから、オブジェクトの関係を絞り込むときに明示的なキャストを行う責任があり、ユーザーはこのために精度が失われることを知っていて問題ありません。ただし、コンパイラは明示的な間違ったキャストを検出CE: Type mismatch errorし、ある時点でスローすることができます。それを超えると、それを処理するのは実行時ClassCastExceptionになります。

コンパイラは、明示的なキャストの次のケースを検出できます。

class A {}
class B {}

A a = (A) new B(); //CE: Type mismatch: cannot convert from B to A
B b = (B) new A(); //compilation error (CE)

interface I {}
final class A {}
I i = (I) new A();  //compilation error

コンパイラは、明示的なキャストの次のケースを検出できません。

class A {}
class B extends A {}
A a = (A) new B(); //Fine
B b = (B) new A(); //Runtime error; because compile time;
                   //compiler wont be able to tell the reference is instance of A or B.
                   //means this is something like below. <BR>
B b = (B) (A) new A();

コンパイル エラーなしで、任意のオブジェクトを任意のインターフェイスにキャストできます。

interface I {}
class A {}
class B extends A implements I{}

I i = (I) new A();  //Runtime error
I i = (I) new B();  //Fine

なぜこれがコンパイルされるのですか?

インターフェイスの参照は、コンパイル エラーなしで任意のオブジェクトにキャストできます。

interface I {}
class A implements I {}
class B {}

B b = (B) getI();     //Runtime error
OR 
B b = (B)(I)new A();  //Runtime error

public I getI() {
 return new A();
}
于 2016-05-12T15:06:01.680 に答える