Java Generics

久々にJavaで開発中。5.0になって以降全然触れてなかったので、Genericsとかもちまちまと触れながらやってます。
で、このGenericsC++のテンプレートみたいなのかと思ったら全然違うのね。今やりたいのはファイルから特定の構造を読み込むということで、そのためにFilterInputStreamを拡張してgetIntとかgetStringとかぐだぐだ作ろうかと思ったんだけど、Little endianとBig Endianの違いにも対処しなくちゃいけなくて、この方法で行くと同じエンディアン変換コードが至る所にコピーされて美しくないなぁと思って、そうだGenericsってこういうとき使えんじゃね、と思ったわけです。
具体的にはこんなことをしたい。

//欲しいコード in C++
//int i = getPrimitive<int>(fp, false);
//short s = getPrimitive<short>(fp, true);
//のように使う。
template<class T> T getPrimitive(FILE *fp, bool littleEndian) {
    unsigned char *buf = new unsigned char[sizeof(T)];
    fread(buf, sizeof(unsigned char), sizeof(T), fp);
    T result = 0;
    for(int i = 0; i < sizeof(T); i++) {
        result |= littleEndian ? (buf[i]<<(8*i)) : (buf[i]<<(8*(sizeof(T)-i-1)));
    }
    delete[] buf;

    return result;
}

しかし、Javaにはsizeofが無いのでこの手法が使えません。それならD言語みたいにtypeid(typeof(T))でif文に入れればいいかと思ったけど、typeofが無いので無理。妥協して引数にサイズを渡して読み込むのも考えたけど、返り値は固定になるので無理。サイズによってプリミティブのWrapperクラスを生成して返して、呼び出し元で(Integer)とかキャストするとUnboxingがあるのでvalueOfは書かなくても済むけど、中の分岐が・・・。
ここまで書いて気づいた。こうすればいいんじゃね?

//in Java
//int i = (Integer)getPrimitive(in, 4, true);
//short s = (Short)getPrimitive(in, 2, false);
//こう使う。UnboxingによってWrapper->Primitiveは自動的に変換される。
Object getPrimitive(InputStream in, int size, boolean littleEndian) {
    byte[] buf = new byte[size];
    in.read(buf, 0, size);
    long result = 0;
    for(int i = 0; i < size; i++) {
        result |= littleEndian ? (buf[i]<<(8*i)) : (buf[i]<<(8*(size-i-1)));
    }
    switch(size) {
        case 2:
            return new Short((short)result);
        case 4:
            return new Integer((int)result);
        case 8:
            return new Long(result);
    }

    throw new IllegalArgumentException("Invalid size.");
}

あれ、これって符号どうなるんだっけ。時間ないので後で試す。

試した。キャストは単純に下位nバイトを取るだけみたいね。この実装の美しくないところは、型をキャストとsizeで2回表現してるところ。特にsizeはMagic Numberになるので見た目もよろしくなさげ。しかし1回の解は思いつかない。
考えられる妥協解は、文字列をテンプレートにしてunpackを実装することか?テンプレートで1回目、取り出すときのキャストで2回目の型表明があるけど、sizeを与えるよりは美しく見える。