CodeGym /Java Blog /ランダム /Operator の Java インスタンス
John Squirrels
レベル 41
San Francisco

Operator の Java インスタンス

ランダム グループに公開済み
やあ!今日は、 instanceof演算子について説明し、その使用例を検討し、その動作のいくつかの側面について触れます:) この演算子は、CodeGym の初期レベルですでに使用されています。なぜそれが必要なのか覚えていますか? そうでなくても、心配する必要はありません。一緒に覚えていきましょう。instanceof演算子は、 X変数によって参照されるオブジェクトが何らかのYクラスに基づいて作成されたかどうかを確認するために必要です。それは簡単なことのように思えます。なぜこの話題に戻ったのでしょうか? まず第一に、あなたは Java の継承メカニズムと OOP のその他の原則をよく理解しているからです。これで、 instanceof演算子がより明確になり、その使用方法のより高度な例を見ていきます。さあ行こう!instanceof 演算子の仕組み - 1たぶん、 instanceof演算子は、チェックが true と評価された場合はtrueを返し、式が false の場合はfalseを返すことを覚えているでしょう。したがって、これは通常、あらゆる種類の条件式 ( if…else ) で発生します。いくつかの簡単な例から始めましょう。

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
コンソールには何が表示されると思いますか? まあ、ここでは明らかです。:) xオブジェクトは Integer なので、結果はtrueになります。コンソール出力: TrueそれがString かどうかを確認してみましょう。

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String); // Error!
   }
}
エラーが発生しました。そして注意してください。コンパイラはコードを実行する前にエラーを生成しました。IntegerString は相互に自動的に変換できず、継承によって関連付けられていないことがすぐにわかりました。したがって、 Integer オブジェクトはStringに基づいて作成されません。これは便利で、奇妙な実行時エラーを避けるのに役立ちます。そのため、コンパイラがここで私たちを助けてくれました :) 次に、より難しい例を考えてみましょう。継承について触れたので、次の小さなクラス システムを使ってみましょう。

public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
オブジェクトがクラスのインスタンスであるかどうかを確認するときに、instanceof がどのように動作するか はすでにわかっていますが、親子関係を考慮するとどうなるでしょうか? たとえば、これらの式から何が得られると思いますか?

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();

       System.out.println(cat instanceof Animal);

       System.out.println(cat instanceof MaineCoon);

   }
}
出力: True False 答えなければならない主な質問は、instanceof が「クラスに基づいて作成されたオブジェクト」をどのように解釈するかということです。「catinstanceofAnimal」はtrueと評価されますが、確かにその文言の誤りを見つけることができます。CatオブジェクトがAnimalクラスに基づいて作成されるのはなぜですか? 独自のクラスだけを基にして作成されていませんか? 答えはとても簡単で、あなたもすでに考えているかもしれません。オブジェクトの作成時にコンストラクターが呼び出され、変数が初期化される順序を覚えておいてください。このトピックについては、クラス コンストラクターに関する記事ですでに説明しました。そのレッスンの例を次に示します。

public class Animal {

   String brain = "Initial value of brain in the Animal class";
   String heart = "Initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("Animal base class constructor is running");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("Current value of static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in the Animal class = " + this.brain);
       System.out.println("Current value of heart in the Animal class = " + this.heart);
       System.out.println("Have the variables of the Cat class already been initialized?");
       System.out.println("Current value of static variable catCount = " + Cat.catCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor is done!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

public class Cat extends Animal {

   String tail = "Initial value of tail in the Cat class";

   static int catCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The Cat class constructor has started (The Animal constructor already finished)");
       System.out.println("Current value of static variable catCount = " + catCount);
       System.out.println("Current value of tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value of tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
これを IDE で実行すると、コンソール出力は次のようになります。 Animal 基本クラス コンストラクターが実行中です Animal クラスの変数はすでに初期化されていますか? 静的変数animalCountの現在値 = 7700000 Animalクラスのbrainの現在値 = Animalクラスのbrainの初期値 Animalクラスのheartの現在値 = Animalクラスのheartの初期値 Catクラスの変数がすでにある初期化されてる?静的変数 catCount の現在の値 = 37 Animal 基本クラスのコンストラクターが完成しました。Brain の現在値 = Brain 現在値 heart = Heart cat クラスのコンストラクタが開始されました (Animal コンストラクタは既に終了しています) 静的変数 catCount の現在値 = 37 tail の現在値 = Cat クラスの tail の初期値 tail の現在値 =しっぽ 覚えていますか?:) 基底クラスがある場合、オブジェクトの作成時に基底クラスのコンストラクターが常に最初に呼び出されます。instanceof演算子は、 AオブジェクトがBクラスに基づいて作成されたかどうかを判断するときに、この原則に従っています。基本クラスのコンストラクターが呼び出されれば、疑いの余地はありません。2 番目のチェックでは、すべてがより簡単になります。

System.out.println(cat instanceof MaineCoon);
Catオブジェクトの作成時に MaineCoon コンストラクターが呼び出されなかったのは当然の ことです結局のところ、メインクーンはキャットの子孫であり、祖先ではありません。また、これはCatのテンプレートではありません。さて、それについては明らかだと思います。しかし、これを実行するとどうなるでしょうか?:

public class Main {

   public static void main(String[] args) {

       Cat cat = new MaineCoon();

       System.out.println(cat instanceof Cat);
       System.out.println(cat instanceof MaineCoon);


   }
}
うーん...今はそれが難しいです。話し合ってみましょう。MaineCoonオブジェクトを割り当てたCat変数があります。ところで、なぜそれがうまくいくのでしょうか?それはできますよね?はい、できます。結局のところ、すべてのメインクーンは猫です。それが完全に明確でない場合は、拡張プリミティブ型の例を思い出してください。

public class Main {

   public static void main(String[] args) {

       long x = 1024;

   }
}
数値1024は短いです。これを収容するのに十分なバイトがあるため、長い変数に簡単に適合します(人形の例を覚えていますか?)。 子孫オブジェクトは常に祖先変数に割り当てることができます。現時点では、これだけを覚えておいてください。後続のレッスンで、それがどのように機能するかを分析します。それでは、この例では何が出力されるのでしょうか?

Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
インスタンスは 何をチェックするのでしょうか? Cat変数ですか、それともMaineCoonオブジェクトですか? 答えは、この質問は実は簡単です。演算子の定義をもう一度読むだけで済みます。instanceof演算子は、 X変数によって参照されるオブジェクトが何らかのYクラスに基づいて作成されたかどうかを確認するために必要です。instanceof演算子は、変数の型ではなく、オブジェクトの起源をテストします。したがって、この例では、プログラムは両方の場合にtrueを表示します。MaineCoonオブジェクトがあります。明らかにMaineCoonクラスに基づいて作成されましたが、 Catに基づいて作成されました保護者クラスも!
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION