0

以下のコードがコンパイルされます。

class Robot { }  
interface Animal { }  
class Feline implements Animal { }  
public class BarnCat extends Feline {  
    public static void main(String[] args) {  
        Animal af = new Feline();  
        Feline ff = new Feline();  
        BarnCat b = new BarnCat();  
        Robot r = new Robot();  
        if(af instanceof Animal) System.out.print("1 ");  
        if(af instanceof BarnCat) System.out.print("2 ");  
        if(b instanceof Animal) System.out.print("3 ");  
        if(ff instanceof BarnCat) System.out.print("4 ");  
        if(r instanceof Animal) System.out.print("5 ");  
    }  
}  

これはコンパイル時エラーをスローします

public class One{  
    public static void main(String[] args) {  

        One o = new One();  
        if(o instanceof Two) {  
           System.out.println("Yes");  
        } else {  
            System.out.println("No");  
        }  
    }  
 }  
 class Two{}  

なぜそうなのですか?どちらの場合も本質的に非常に似ていますか?

4

6 に答える 6

3

instanceof実行時にチェックを行います。ただし、コンパイラはコンパイル時にこれが真実ではなく、スマートであることを伝えることができます:)

15.20.2を参照してください。型比較演算子 instanceof :

RelationalExpression の ReferenceType へのキャストがコンパイル時エラーとして拒否される場合、instanceof 関係式も同様にコンパイル時エラーを生成します。このような状況では、instanceof 式の結果が true になることはありません。

于 2013-10-17T13:47:02.037 に答える
2

oコンパイラは、インスタンスが可能な方法でクラスになる可能性がないことを知るのに十分賢いためですTwo

したがって、このifステートメントは常に false を返すため、意味がありません。

たとえば、 classesOneTwoextends basic classの両方Objectです。次のようなことができます:

One one = new One();
Two two = new Two();

Object o1 = one;
Object o2 = two;

if (o1 instanceof One) { ... }

インスタンスをそのインスタンスの祖先である型の変数に保存すると、それObjectOneまたはTwoまたは他のクラスであるかどうかは完全に明確ではないため、これは理にかなっています

于 2013-10-17T13:46:57.497 に答える
1

oオブジェクトがinstanceofクラス 2であることはあり得ません。その場合Two extends One、コンパイル エラーは修正されます。

于 2013-10-17T13:48:17.847 に答える
0

jls-15.20.2から

演算子の RelationalExpression オペランドの型はinstanceof、参照型または null 型でなければなりません。そうしないと、コンパイル時エラーが発生します。

instanceof 演算子の後に記述された ReferenceType が具体化可能な参照型を示さない場合、コンパイル時エラーになります (§4.7)。

RelationalExpression の ReferenceType へのキャストがコンパイル時エラーとして拒否される場合、instanceof関係式も同様にコンパイル時エラーを生成します。このような状況では、instanceof式の結果が真になることはありません。

class Point   { int x, y; }
class Element { int atomicNumber; }
class Test {
public static void main(String[] args) {
    Point   p = new Point();
    Element e = new Element();
    if (e instanceof Point) {  // compile-time error (you are checking o instanceof Two)
        System.out.println("I get your point!");
        p = (Point)e;  // compile-time error
    }
 }
}  

このプログラムでは、コンパイル時に 2 つのエラーが発生します。(Point)eElement のインスタンスも、その可能なサブクラス (ここには表示されていません) も、Point のサブクラスのインスタンスになる可能性がないため、キャストは正しくありません。instanceofまったく同じ理由で、表現は正しくありません。一方、クラスPointが のサブクラスである場合Element

補足:instanceof演算子を使用するnull場合、これは何のインスタンスでもないことに注意してください。

于 2013-10-17T13:49:46.040 に答える
0

静的型は でoあることが知られていますOne。コンパイラーは、オブジェクトOneがオブジェクトになれないことTwoを認識しています ( Two「別の階層」であるため)。

から派生したインターフェイスまたはクラスの場合可能です。TwoOne

于 2013-10-17T13:47:44.287 に答える
0

クラス 2 はクラス 1 とは関係ありません。クラス 1 とクラス 2 の間に共通のインターフェイスや継承関係は存在しません。そのため、例外がスローされます。

于 2013-10-17T13:47:51.977 に答える