Javaのメソッドで引数にnullを指定した場合のオーバーロードメソッドの解決

オーバーロードメソッドの引数にnullを直接指定するとメソッドを解決できる場合とできない場合がある。

このような継承関係のクラスがあるとき、

class HogeA {}
class HogeB extends HogeA {}
class HogeC extends HogeA {}
 
public class Test1 {
    public static void test(HogeA hoge){}
    public static void test(HogeB hoge){}
    public static void main(String[] args) {
        test(null);
    }
}

この場合、test(null);はTest1#test(HogeB)として解決される。オーバーロードメソッドの引数に継承関係がある場合は、サブクラスを引数にしているメソッドが呼ばれる。

public class Test2 {
    public static void test(HogeB hoge){}
    public static void test(HogeC hoge){}
    public static void main(String[] args) {
        test(null);
    }
}

これはTest2#test(HogeB)、Test2#test(HogeC)どちらを呼びたいのか判断できない、と言われてコンパイルエラーとなる。引数のクラスに継承関係が無い場合、null指定ではオーバーロードメソッドを解決できない。

こういう引数が単純なメソッドでnullを直接記述することは少ないと思うが、オーバーロードメソッドに引数に直接nullを書くのは止めた方がいいだろう。できればnullオブジェクトパターン等で代用するといいのではないか。なお、Test2クラスは、

test((HogeC)null);

のようにコンパイラが引数の型を判断できるようにすればコンパイルできる。