Zenn
📘

var 〜ワイルドカード〜

2025/04/10に公開

*厳密でなければごめんなさい。黒本参照。

みなさん、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

ログインするとコメントできます