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);
- }
- }
© 2006 矢木浩人