やっぱり java の generic にムキムキしちゃうの - Genericな関数の型指定で死亡

class A<T>
{
    static public interface IHashGetter<T> {
        public int getHash(T t);
    };

    public A() {
        this(getDefaultHashGetter());
        // ※↑コンストラクター A<T>(A.IHashGetter<Object>) は未定義です。
    }
    
    public A(IHashGetter<T> getter) {
        // こっちが本線
    }
    
    static <U> IHashGetter<U> getDefaultHashGetter() {
        return new IHashGetter<U>() {
            public int getHash(U t) {
                return t.hashCode();
            }
        };
    }
};

こんなクラスがあったとします。(処理の内容はともかく:ぉ)

class A のコンストラクタでは "IHashGetter" を要求しますが、用意するときが面倒な時は指定無しにすると、内部で用意したデフォルトの getter を利用する…という感じです。

ただ、上記のコードではデフォルトコンストラクタでエラーが出ちゃいます。うん確かにそりゃそうだよね。U に型指定出来てないもんね……ってことで、型指定(T を渡したい)をするわけですが…ここで躓きました。

C++屋 のノリで指定してみるかしら!

public A() {
    this(getDefaultHashGetter<T>());
    //                        ※↑
    // トークン "(" に構文エラーがあります。
    // このトークンの後には Expression を指定する必要があります。
}

oh...

そういえば、Javaは型指定を関数の前に付けるんだっけか…


java屋さんのノリで指定してみるかしら!

public A() {
    this(<T>getDefaultHashGetter());
    // ※↑
    // トークン "<" に構文エラーがあります。
    // このトークンを削除してください。
}

……どうしろと。





悩んだあげく、私はひらめきピッカリン! ダミーの引数をあたえて自動的に型推論作戦 かしら!

型推論してみるかしら! - その1

public A() {
    this(getDefaultHashGetter(new T()));
    //                           ※↑
    // 型 T のインスタンスを生成できません。
}

static <U> IHashGetter<U> getDefaultHashGetter(U dummy) {
    return new IHashGetter<U>() {
        public int getHash(U t) {
            return t.hashCode();
        }
    };
}

_no

generic で指定した型は new 出来ないんだった…。 ってか、そもそも勝手に new するのも場合によっちゃ危険かもしれんしなぁ。




ほいじゃぁ、インスタンスは作らないけど、nullで初期化した変数だけ用意して「型」だけ引っ張って来ちゃるかしら…ッ!

型推論してみるかしら! - その2

public A() {
    T t = null;
    this(getDefaultHashGetter(t));
    // ※↑
    // コンストラクター呼び出しは、
    // コンストラクター内の最初のステートメントである必要があります。
}

static <U> IHashGetter<U> getDefaultHashGetter(U dummy) {
    return new IHashGetter<U>() {
        public int getHash(U t) {
            return t.hashCode();
        }
    };
}

むおおおおおおおおお!!! orz

そうだよなぁ…。 this() とか super() の前に、ステートメントがあると駄目なんだった…




……ってか、えぇえええ!? んじゃぁそうすりゃえぇってのよ……! おしえて!はてなよ○せいさんッ!


悩んだ果てに...

public A() {
    this(A.<T>getDefaultHashGetter()); // OK
}

static <U> IHashGetter<U> getDefaultHashGetter() {
    return new IHashGetter<U>() {
        public int getHash(U t) {
            return t.hashCode();
        }
    };
}

A. で名前解決しなきゃ行けないとかマジ何それ

class A のコンストラクタの中におるのに、更に A. が必要とかさーもー。ああああ orz