📘
var 〜ワイルドカード〜
*厳密でなければごめんなさい。黒本参照。
みなさん、varしてますか。
突然ですが問題。
黒本第2章第8問です。
A.java
public class A {
public void test() {
System.out.println("A");
}
}
B.java
public class B extends A {
@Override
public void test() {
System.out.println("B");
}
}
C.java
public class C extends A {
@Override
public void test() {
System.out.println("C");
}
}
Main.java
public class Main {
public static void main(String[] args) {
var a = new B();
a = new c();
a.test();
}
}
コンパイル、実行するとどうなる?
A. コンパイルエラー
B. 実行時例外がスロー
C. Aが表示される
D. Bが表示される
E. Cが表示される
どれでしょう。
答えは、A。コンパイルエラーになります。(いかにもCと出力して欲しそうなプログラムですが)
なぜか。
Main.java
public class Main {
public static void main(String[] args) {
var a = new B();
a = new c();
a.test();
}
}
Main.javaに問題があります。
3行目の var です。そもそも var とはなんぞや、と。
varは変数を宣言するときに用います。普通変数に整数を代入するなら
int a = 1;
のように書きますよね。ここで、varを使うと
var a = 1;
同じく代入できます。
これ何が起きているかっていうと、1で初期化するときに、varが1を感知して、自動でaをint型にするんですね。これを型推論と言います。varはワイルドカードなんですね。
ただ色々制約もあって、
*宣言と初期化を同時に行わなければならない
*ローカル変数にしか使えない(フィールドの初期化には使えない)
などなど、色々難しいみたいです。
それを踏まえて、こちら。
Main.java
public class Main {
public static void main(String[] args) {
var a = new B();
a = new c();
a.test();
}
}
3行目で、aの型はB型ともう決まりました。これは変更されません。
よって、4行目でB型であるaに、C型のインスタンスを参照させようとしても、うまくいかないんですね。互換性もないので。
一つの学びでした。
Discussion