!!!SJC-P ジェネリックス 型パラメータ !型パラメータ(クラス) 以下のような箇所で使用できる *クラスの型 *インスタンス変数の型 *配列の型 *コレクション等、他の型パラメータに渡す *メソッド引数 *メソッド戻値 *キャスト ::通常 import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Date; import java.util.List; public class GenericsTest4 { public static void main(String[] args) { GenericsTest4 me = new GenericsTest4(); GenTypeTest gd = me.new GenTypeTest(); for (int i=0; i<5; i++) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } Date d = new Date(); gd.addMember(d); } Date[] da = gd.getMemberAry(); for (Date d : da) { System.out.println(d.toString()); } } private class GenTypeTest { // クラスの型 private T member; // インスタンス変数の型 private T[] members; // 配列の型 private List memList // コレクションに渡す = new ArrayList(); private void addMember(T member) { // 引数 memList.add(member); } private T[] getMemberAry() { // 戻値 // members = new T[memList.size()]; // NG インスタンスの生成 member = memList.get(0); members = (T[])Array.newInstance( // キャスト member.getClass(), memList.size()); memList.toArray(members); return members; } } } ::継承関係を指定 * で、指定クラス(インターフェース)の派生クラスであることを指定 * Clazz で、Clazzが、指定クラス(インターフェース)の基底クラスであることを指定 import java.util.ArrayList; import java.util.Collections; import java.util.List; public class GenericsTest5 { public static void main(String[] args) { GenericsTest5 me = new GenericsTest5(); CompareUtil dc = me.new CompareUtil(); dc.addNum(1.23); dc.addNum(2.34); dc.addNum(100.00); dc.addNum(-5.23); System.out.println(dc.getMax()); } // T型の基底クラス(T型を含む)に適応する Comparable を継承した T型 private class CompareUtil> { List numList = new ArrayList(); public void addNum(T num) { numList.add(num); } public T getMax() { Collections.sort(numList); return numList.get(numList.size()-1); } } } !メソッドでジェネリックス型を利用する *戻値より前に書く必要がある *?は使えない(よく考えればわかる) public class GenericsTest6 { public static void main(String[] args) { System.out.println(MathUtil.log10(365)); System.out.println(MathUtil.log10(0.56789)); // ボクシングと絡めて利用すると、挙動がややこしい // 上の例 MathUtil.log10(365) はOKだが、ここで同様にすると、エラー // オートボクシングにより、365 → Integer になり、戻値も Integer // アンボクシングにより、Integer → int で、Math.pow(double, double)に適合しなくなる // (Doubleにアンボクシングできない:java.lang.ClassCastException: java.lang.Double) System.out.println(Math.pow(10,MathUtil.log10(365.0))); System.out.println(Math.pow(10,MathUtil.log10(0.56789))); } } class MathUtil { // メソッドで、ジェネリクス型を使う // いろいろバージョンをオーバーロードしなくてもよい public static T log10(T num) { double ret = Math.log10(num.doubleValue()); return (T) new Double(ret); } } !拡張forループで使用する Messageクラスを保持するMessagesクラスを拡張forループに対応させる *Iterableの実装 public class Messages implements Iterable { private List messages; private List getMessages(){ if (this.messages == null) { this.messages = new ArrayList(); } return this.messages; } public Iterator iterator() { return getMessages().iterator(); } public void add(int index, Message msg) { getMessages().add(index, msg); } public Message get(int index) { return getMessages().get(index); } }