プチ修羅場中に見つけたオーバーロードが出来なくてぐんにょりしてしまったケース

ソース

import java.util.List;
import java.util.ArrayList;

public class a
{
    class Kanaria{};
    class Shinku{};
    
    static void func(List<Kanaria> kana_list) {
        
    }
    
    static void func(List<Shinku> shinku_list) {
        
    }

    public static void main(String[] argv) {
        ArrayList<Kanaria> kana_list = new ArrayList<Kanaria>();
        func(kana_list);
    }
};

コンパイル結果

a.java:9: 名前が競合しています。func(java.util.List) と func(java.uti
l.List) は削除後の名前が同じです。
        static void func(List kana_list) {
                    ^
a.java:13: 名前が競合しています。func(java.util.List) と func(java.uti
l.List) は削除後の名前が同じです。
        static void func(List shinku_list) {
                    ^
エラー 2 個

ええええええええ


ってかそうか…確かにオーバーロード出来ないよなぁ…。 Generic の型引数は無い事になるんだもんなぁー…

というわけでこうした

import java.util.List;
import java.util.ArrayList;

public class a
{
    class Kanaria{};
    class Shinku{};
    
    static void func(List<Kanaria> kana_list, Kanaria[] dummy) {
        
    }
    
    static void func(List<Shinku> shinku_list, Shinku[] dummy) {
        
    }

    public static void main(String[] argv) {
        ArrayList<Kanaria> kana_list = new ArrayList<Kanaria>();
        func(kana_list, new Kanaria[]{});
    }
};

タグディスパッチ!(っぽいの)


型情報のみの引数を余分につけてあげればオーバーロードを解決できていい感じです。 配列にした所が重要で、こうすりゃその型のオブジェクト自身を new しなくて済む故に、無駄なでかいオブジェクトを生成するコストも無い為良い感じ。 ついでに Kanaria / Shinku が interface でも対応できるようになるのはおいしい所。*1



C++ の template の知識が役に立ったかしら!! HAHAHA!!

*1:んまぁぶっちゃけ int とか double とかでもいいんだけどね