| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

「SJC-P ジェネリックス 型パラメータ」の版間の差分

提供: MyMemoWiki
ナビゲーションに移動 検索に移動
(ページの作成:「==SJC-P ジェネリックス 型パラメータ== ====型パラメータ(クラス)==== 以下のような箇所で使用できる *クラスの型 *インスタ…」)
 
20行目: 20行目:
 
         GenericsTest4 me = new GenericsTest4();
 
         GenericsTest4 me = new GenericsTest4();
 
          
 
          
         GenTypeTest<Date> gd = me.new GenTypeTest<Date>();
+
         GenTypeTest&lt;Date&gt; gd = me.new GenTypeTest&lt;Date&gt;();
         for (int i=0; i<5; i++) {
+
         for (int i=0; i&lt;5; i++) {
 
             try {
 
             try {
 
                 Thread.sleep(500);
 
                 Thread.sleep(500);
35行目: 35行目:
 
         }
 
         }
 
     }
 
     }
     private class GenTypeTest<T> {          // クラスの型
+
     private class GenTypeTest&lt;T&gt; {          // クラスの型
 
         private T member;                    // インスタンス変数の型
 
         private T member;                    // インスタンス変数の型
 
         private T[] members;                // 配列の型
 
         private T[] members;                // 配列の型
         private List<T> memList              // コレクションに渡す
+
         private List&lt;T&gt; memList              // コレクションに渡す
             = new ArrayList<T>();
+
             = new ArrayList&lt;T&gt;();
 
         private void addMember(T member) {  // 引数
 
         private void addMember(T member) {  // 引数
 
             memList.add(member);
 
             memList.add(member);
55行目: 55行目:
 
  }
 
  }
 
=====継承関係を指定=====
 
=====継承関係を指定=====
* <T extends [Class or Interface]> で、指定クラス(インターフェース)の派生クラスであることを指定
+
* &lt;T extends [Class or Interface]&gt; で、指定クラス(インターフェース)の派生クラスであることを指定
* Clazz<? super [Class or Interface]> で、Clazzが、指定クラス(インターフェース)の基底クラスであることを指定
+
* Clazz&lt;? super [Class or Interface]&gt; で、Clazzが、指定クラス(インターフェース)の基底クラスであることを指定
 
  import java.util.ArrayList;
 
  import java.util.ArrayList;
 
  import java.util.Collections;
 
  import java.util.Collections;
65行目: 65行目:
 
         GenericsTest5 me = new GenericsTest5();
 
         GenericsTest5 me = new GenericsTest5();
 
          
 
          
         CompareUtil<Double> dc = me.new CompareUtil<Double>();
+
         CompareUtil&lt;Double&gt; dc = me.new CompareUtil&lt;Double&gt;();
 
         dc.addNum(1.23);
 
         dc.addNum(1.23);
 
         dc.addNum(2.34);
 
         dc.addNum(2.34);
73行目: 73行目:
 
     }
 
     }
 
     // T型の基底クラス(T型を含む)に適応する Comparable を継承した T型
 
     // T型の基底クラス(T型を含む)に適応する Comparable を継承した T型
     private class CompareUtil<T extends Comparable<? super T>> {
+
     private class CompareUtil&lt;T extends Comparable&lt;? super T&gt;&gt; {
         List<T> numList = new ArrayList<T>();
+
         List&lt;T&gt; numList = new ArrayList&lt;T&gt;();
 
         public void addNum(T num) {
 
         public void addNum(T num) {
 
             numList.add(num);
 
             numList.add(num);
104行目: 104行目:
 
     // メソッドで、ジェネリクス型を使う
 
     // メソッドで、ジェネリクス型を使う
 
     // いろいろバージョンをオーバーロードしなくてもよい
 
     // いろいろバージョンをオーバーロードしなくてもよい
     public static <T extends Number> T log10(T num) {
+
     public static &lt;T extends Number&gt; T log10(T num) {
 
         double ret = Math.log10(num.doubleValue());
 
         double ret = Math.log10(num.doubleValue());
 
         return  (T) new Double(ret);
 
         return  (T) new Double(ret);
111行目: 111行目:
 
====拡張forループで使用する====
 
====拡張forループで使用する====
 
Messageクラスを保持するMessagesクラスを拡張forループに対応させる
 
Messageクラスを保持するMessagesクラスを拡張forループに対応させる
*Iterable<Message>の実装
+
*Iterable&lt;Message&gt;の実装
  
  public class Messages implements Iterable<Message> {
+
  public class Messages implements Iterable&lt;Message&gt; {
     private List<Message> messages;
+
     private List&lt;Message&gt; messages;
     private List<Message> getMessages(){
+
     private List&lt;Message&gt; getMessages(){
 
         if (this.messages == null) {
 
         if (this.messages == null) {
             this.messages = new ArrayList<Message>();
+
             this.messages = new ArrayList&lt;Message&gt;();
 
         }
 
         }
 
         return this.messages;
 
         return this.messages;
 
     }
 
     }
     public Iterator<Message> iterator() {
+
     public Iterator&lt;Message&gt; iterator() {
 
         return getMessages().iterator();
 
         return getMessages().iterator();
 
     }
 
     }

2020年2月15日 (土) 08:05時点における版

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);
    }
}