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つの質問:
- 上記のコードがまったくコンパイルされないのはなぜですか?電話は私にとってローミング可能とは無関係のようですか?
- なぜコードがコンパイルされますか
new Phone()
、しかし「コンパイルしない」new String()
?
回答:
回答№1の13上記のコードがまったくコンパイルされないのはなぜですか?電話とは無関係のようです 私にローミング可能?
はい、なぜなら Roamable
インターフェースである場合、ランタイム例外を引き起こす可能性がありますが、コンパイル時例外は生じません。 Phone
実装していない Roamable
のサブクラス Phone
可能性があります、したがって、コンパイラは実行時以外はそれを知る方法がありません。
Java言語仕様で既に定義されています。 ここで私の答えをチェックしてください.
コードが新しいPhone()でコンパイルされるのに、コンパイルされないのはなぜですか 新しいString()で?
なぜなら class String
として宣言されています public final class
に java.lang
パッケージ。で指定されている jls 8.1.1.2 final class
セクション:として宣言されたクラス final
「拡張できないため、サブクラスはありません」。そのため、コンパイラはすでにそれを知っています String
「拡張できない:したがって、サブクラスの存在は実装できません」 インタフェース Roamable
編集:(以下のコメントへの返信付き)
仮定しましょう B
のサブクラスです A
インターフェースを実装します T
.
次のステートメント:
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.
したがって、ここでのスーパークラスとサブクラスの本当の理由は参照です。の aObj
この2番目のコード例のクラスは、クラスのインスタンスでもあります A
しかし、それはクラスのインスタンスでもあります B
実装しました T
.
回答№2の場合は3
文字列は最終的なものであるため、Roamableにキャストする方法はありません。
回答№3の場合は1
コンパイラにより次のことができるため、コードがコンパイルされます。何にもキャストします。これはプログラマーによる明示的なアクションであり、コンパイラーはリスクを評価し、適切な予防措置を講じていると想定します。
String
のインスタンスではありません Roamable
ので、のインスタンスを割り当てることはできません String
〜に Roamable
参照。そして、それはコンパイル時に決定できるため、失敗します。
回答№4の場合は1
new Phone()
クラスに評価する Phone
、 できた の延長である Phone
実装する Roamable
(コンパイラに関する限り)。
電話をした場合 final
クラス(Stringなど)、コンパイラエラーが表示されます。
回答№5の場合は0
いい質問です。 new Phone()
間違いなくサブクラスではありません Phone
。ただし、その情報は失われますが、javacは Phone
そこに入力してください 正確 Phone
タイプ。
関連する仕様: http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.5.1
Sが最終クラス(§8.1.1)の場合、SはTを実装する必要があり、
仕様は次のように修正できます
式がクラスインスタンス作成式(§15.9)の場合、式のタイプはTのサブタイプである必要があります。
答え№6の場合は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();
}