ジェネリクスを使いこなそうゼ
というネタでエントリ書けよゴルァ、とid:happy_ryoに脅されて書くエントリー。
ジェネリクスご存知ですか。使ってますか。アノテーションと共にJava5から現れた、<> で囲まれた変な奴。
全くの余談ですが、アノテとジェネリクスの事を理解していなかったその昔。漠然と「たまに見かけるあの@とか、<> とかって何だろう」と思った訳ですよ。で、どうしようもなくて某所で聞いてみたんですね。そしたらさー、「ググれカス」って言われちゃってさwwww
「Java @」とか「Java <>」で検索してみるわけですよw 無理だろww
はい、話し始める前から脱線してる都元ですコンバンワ。
ジェネリクス初心者がまず触れるのは、コレクションですかね。List
じゃあ、自分でジェネリクスを定義して使ってみようぜ、というのが今日のテーマ。いささか初歩的なんじゃなかろか、とか思ってたけど、某skypeチャットルームで世界の「Ryo Iwama」に脅されたので書いてみる。
ジェネリクスってgeneralの派生単語で、「一般」とかいう意味ですね。Java的な訳は「総称型」とか言ったりするようです。ではコイツは何を一般化して、何を総称してるのか。
ちょっと List のコードを見てみましょか。
public interface List<E> { boolean add(E o); E get(int index); }
かなり省略しましたがw こんな感じです。ここで、add/getされる対象を「一般化」「総称」する役割を担ってるのがジェネリクス。インターフェイスでは一般的(色んなモノに使えるように)に書いておいて、実際に使う時に用途を限定する、という使い方をします。
List<String> list = new ArrayList<String>();
って奴ですね。こうすることによって、一般的に書かれたListが、「Stringしか入れられないList」に特殊化する。
もうちょっと応用すると、こんな事もできる。
class StringList implements List<String> { // ... }
こうして作られたStringList型にはStringしか入れられない。
じゃーさじゃーさ、Listインターフェイスに倣って、自分で色々クラスを定義してみようよ。
interface Processor<T> { T process(T input); } class StringProcessor implements Processor<String> { public String process(String input) { ... } } class IntegerProcessor implements Processor<Integer> { public Integer process(Integer input) { ... } }
入力した何かを「処理(process)」するクラス。型が違っても一般的に書けました。
複数のジェネリクスを定義することもできる。
interface Converter<S, D> { D convert(S source); } class IntegerToStringConverter implements Converter<Integer, String> { public String convert(Integer source) { retrun source.toString(); } } class MapToCollectionConverter implements Converter<Map, Collection> { public Collection convert(Map source) { retrun source.values(); } }
こんな感じか。というわけで「型だけ違うんだけど、似たような型を抽象化したい」って時に、ジェネリクスを自分で定義してみる、というのはいかがだろーか。
最後にオマケ。昔書いたネタだけど。
interface Hoge<T extends Exception> { void process() throws T; } class Fuga implements Hoge<FugaException> { public void process() throws HogeException { ... } } class Piyo implements Hoge<RuntimeException> { public void process() { ... } }
ジェネリクスによって、投げる例外を一般化してる。しかも「Runtimeであれば、throws句がいらないの法則」を利用して、「チェック例外は投げません」ということを表現してみた。これはひどい。
ココまで来ると、オシゴト的には誰も理解してくれなくなるので、やめましょうw
いじょ。