はじめに
javaのinstanceofを勉強していて少し引っかかった箇所があるので、軽くまとめてみます。
コード例
public class Main {
public static void main(String[]args) {
A a = new A();
B b = new B();
ins(a);
ins(b);
}
public static void ins(Object obj) {
if(obj instanceof A a) {
System.out.println(a.getName() + " == A");
}else {
System.out.println("False");
}
}
}
class A{
String name = "A";
String getName() {
return this.name;
}
}
class B extends A{
String name = "B";
String getName() {
return this.name;
}
}
//実行結果
A == A
B == A
instanceofでは、左記インスタンス(今回の場合obj)と右記の型を判定し、互換性がある場合にtrueを返します。
型が完全に一致しているかではなく、互換性があるかを判定するため、例に挙げたAのサブクラスBのインスタンスに対してもtrueを返します。
また、instanceofでは、obj instanceof A aのように、型判定と同時にその型の変数を宣言することができます。
この変数の有効範囲は、その条件式に依存するブロック内のみです。
public class Main {
public static void main(String[]args) {
A a = new A();
B b = new B();
ins(a);
ins(b);
}
public static void ins(Object obj) {
if(obj instanceof A a) {
System.out.println(a.getName() + " == A");//ここではaを利用可能
}else {
System.out.println(a.getName() + " != A");//これはコンパイルエラー(aの有効範囲外)
}
}
}
以下の場合どうでしょう?
public class Main {
public static void main(String[]args) {
A a = new A();
B b = new B();
ins(a);
ins(b);
}
public static void ins(Object obj) {
if(!(obj instanceof A a)) {
System.out.println(a.getName() + " == A");//1
}else {
System.out.println(a.getName() + " != A");//2
}
}
}
この場合、変数aを利用できるのは2の箇所のみです。
instanceofで同時宣言された変数が作成されるのは、instanceofの結果がtrueの場合。
今回は条件式が否定のため、instanceofがtrue = elseブロックに遷移することになります。
したがって、trueブロックでは変数aの利用ができない、というわけです。
おわりに
同時宣言した変数の有効範囲、ややこしいですね...。
私は当初、「trueブロック内のみ利用可能」と単純に覚えていたため、否定の条件式でまんまと引っ掛かりました笑
参考になれば幸いです!