トップ 一覧 ping 検索 ヘルプ RSS ログイン

SJC-P ジェネリックス 型パラメータの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!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<Date> gd = me.new GenTypeTest<Date>();
         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<T> {           // クラスの型
         private T member;                    // インスタンス変数の型
         private T[] members;                 // 配列の型
         private List<T> memList              // コレクションに渡す
             = new ArrayList<T>();
         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;
         }
     }
 }
::継承関係を指定
* <T extends [Class or Interface]> で、指定クラス(インターフェース)の派生クラスであることを指定
* Clazz<? super [Class or Interface]> で、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<Double> dc = me.new CompareUtil<Double>();
         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<T extends Comparable<? super T>> {
         List<T> numList = new ArrayList<T>();
         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 extends Number> T log10(T num) {
         double ret = Math.log10(num.doubleValue());
         return  (T) new Double(ret);
     }
 }
!拡張forループで使用する
Messageクラスを保持するMessagesクラスを拡張forループに対応させる
*Iterable<Message>の実装

 public class Messages implements Iterable<Message> {
     private List<Message> messages;
     private List<Message> getMessages(){
         if (this.messages == null) {
             this.messages = new ArrayList<Message>();
         }
         return this.messages;
     }
     public Iterator<Message> iterator() {
         return getMessages().iterator();
     }
     public void add(int index, Message msg) {
         getMessages().add(index, msg);
     }
     public Message get(int index) {
         return getMessages().get(index);
     }
 }