【Java基礎知識】汎用詳細
1.汎用的な概念:
汎用型はJava SE 1.5の新しい特性であり、汎用型の本質的パラメータ化型、すなわち動作するデータ型は1つのパラメータとして指定される.
2.汎用型を使用するメリット:
(1)安全は簡単で、コードの再利用率を高め、コンパイル時にタイプの安全を検査し、すべての強制タイプ変換は自動的で暗黙的である.
(2)タイプは安全で、後方互換性があり、階層がはっきりしていて、性能が高い.
3.タプルクラスライブラリ(出典:『Thinking Java』)
(1)定義:メタグループとは、一対のオブジェクトを直接パッケージ化して格納する単一のオブジェクトを指し、このコンテナオブジェクトは要素の読み取りを許可するが、新しいオブジェクトの挿入を許可しない.
(2)タプルは任意の長さであってもよく、タプル内のオブジェクトは任意の異なるタイプであってもよい.
例:
4.単純汎用型の定義
(1)汎用クラス:1つ以上のタイプ変数を持つクラス
(2)汎用方法:
例:
(3)汎用インタフェース例:
(4)匿名内部クラスに汎用的に適用する例:
5.汎用消去
(1)定義;javaバイトコードには汎用タイプ情報は含まれていない.コンパイラはコンパイル段階で汎用情報を削除し、実行時にタイプ情報を加える.
(2)異なる種類の消去
例:
(3)リロード中のタイプ消去
例:
6.汎用的な境界
(1)限定タイプ:
汎用的に消去動作があるため,ObjectのtoString(),equals(),hashCode()…メソッドを呼び出すしかないが,制限を加えると,でDogクラスのメソッドを使用できる.
(2)自己限定タイプ:>
クラスF class F extends Access{}を定義すると、このUはAccessのサブクラスでなければなりません(すなわち、uはAccessに関連する必要があります)
7.ワイルドカード
(1)制限付きワイルドカード
List < ? extends Fruit>サブタイプワイルドカードリストスーパータイプワイルドカード
*生産者消費者モデル補助子:PESC(produce-extends consumer-super)リストからTタイプの要素を読み込むには、このリストをは、その後、リストに要素を追加することはできません. Tタイプの要素をリストに追加するには、このリストをは、後で要素を読み取ることができません. リストが生産され、消費される場合は、リストなどの汎用ワイルドカード宣言リストを使用することはできません.
例:
例2:Collectionsクラスのcopyメソッドは典型的なPECSモデルであり,以下はcopyメソッドのソースコードである.
(2)無境界ワイルドカード
8.制約と限界
(1)基本データ型でタイプパラメータをインスタンス化できない(2)ランタイムタイプクエリ元のタイプ(3)パラメータタイプを作成できない配列にのみ適用
例:
解決策:*ArrayList*を使用するツールクラスArrays.asList()
(4)Varargs警告
抑制警告:@SuppressWarnings("unchecked")またはsafe Varargs
(5)タイプ変数をインスタンス化できない(6)汎用クラスの静的コンテキストでタイプ変数が無効(7)汎用クラスのインスタンスを投げ出したり捕獲したりできない(8)消去後の衝突を防ぐ
汎用型はJava SE 1.5の新しい特性であり、汎用型の本質的パラメータ化型、すなわち動作するデータ型は1つのパラメータとして指定される.
2.汎用型を使用するメリット:
(1)安全は簡単で、コードの再利用率を高め、コンパイル時にタイプの安全を検査し、すべての強制タイプ変換は自動的で暗黙的である.
(2)タイプは安全で、後方互換性があり、階層がはっきりしていて、性能が高い.
3.タプルクラスライブラリ(出典:『Thinking Java』)
(1)定義:メタグループとは、一対のオブジェクトを直接パッケージ化して格納する単一のオブジェクトを指し、このコンテナオブジェクトは要素の読み取りを許可するが、新しいオブジェクトの挿入を許可しない.
(2)タプルは任意の長さであってもよく、タプル内のオブジェクトは任意の異なるタイプであってもよい.
例:
// 1 , 1
class OneTuple<A> {
//code
}
// 2 ,
class TwoTuple<A,B> {
//code
}
4.単純汎用型の定義
(1)汎用クラス:1つ以上のタイプ変数を持つクラス
public class Pair<T> {
private T first;
private T second;
public Pair(T first, T second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return this.first;
}
public void setFirst(T newValue) {
this.first = newValue;
}
}
(2)汎用方法:
例:
//
public class ArrayAlg {
//...
public <T> T getMiddle(T... a) {
return a[a.length/2];
}
}
//
class ArrayListTest {
public <T> List<T> list() {
return new ArrayList<T>();
}
}
(3)汎用インタフェース例:
public interface Generator<T> {
T next();
}
(4)匿名内部クラスに汎用的に適用する例:
public class Customer {
public Generator<Customer> clerk() {
return new Generator<Customer>() {
@Override
public Customer next() {
return new Customer();
}
};
}
}
5.汎用消去
(1)定義;javaバイトコードには汎用タイプ情報は含まれていない.コンパイラはコンパイル段階で汎用情報を削除し、実行時にタイプ情報を加える.
(2)異なる種類の消去
例:
public class ErasedTypeEquairalence{
public static void main(String[] args) {
Class c1 = new ArrayList<String>().getClass();
Class c2 = new ArrayList<Integer>().getClass();
System.out.println(c1 == c2);
}
}
// : true
(3)リロード中のタイプ消去
例:
class HoldItem <T,V>{
public void f(List<T> t) {} // error
public void f(List<V> v) {}
public void f(List<T> t,List<V> v) {}
}
6.汎用的な境界
(1)限定タイプ:
汎用的に消去動作があるため,ObjectのtoString(),equals(),hashCode()…メソッドを呼び出すしかないが,制限を加えると,
(2)自己限定タイプ:
クラスF class F extends Access{}を定義すると、このUはAccessのサブクラスでなければなりません(すなわち、uはAccessに関連する必要があります)
7.ワイルドカード
(1)制限付きワイルドカード
List < ? extends Fruit>サブタイプワイルドカードリストスーパータイプワイルドカード
*生産者消費者モデル補助子:PESC(produce-extends consumer-super)
例:
public <T extends Dog> void get1(List<T extends Dog> list){
list.get(0);
}
//error
public <T extends Dog> void set1(List<T extends Dog> list, Dog dog){
list.add(dog);
}
//error
public <T super Cat> void get2(List<T super Cat> list){
list.get(0);
}
public <T super Cat> void set2(List<T super Cat> list, Cat cat){
list.add(cat);
}
例2:Collectionsクラスのcopyメソッドは典型的なPECSモデルであり,以下はcopyメソッドのソースコードである.
/**
* Copies all of the elements from one list into another. After the
* operation, the index of each copied element in the destination list
* will be identical to its index in the source list. The destination
* list must be at least as long as the source list. If it is longer, the
* remaining elements in the destination list are unaffected. <p>
*
* This method runs in linear time.
*
* @param <T> the class of the objects in the lists
* @param dest The destination list.
* @param src The source list.
* @throws IndexOutOfBoundsException if the destination list is too small
* to contain the entire source List.
* @throws UnsupportedOperationException if the destination list's
* list-iterator does not support the <tt>set</tt> operation.
*/
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
int srcSize = src.size();
if (srcSize > dest.size())
throw new IndexOutOfBoundsException("Source does not fit in dest");
if (srcSize < COPY_THRESHOLD ||
(src instanceof RandomAccess && dest instanceof RandomAccess)) {
for (int i=0; i<srcSize; i++)
dest.set(i, src.get(i));
} else {
ListIterator<? super T> di=dest.listIterator();
ListIterator<? extends T> si=src.listIterator();
for (int i=0; i<srcSize; i++) {
di.next();
di.set(si.next());
}
}
}
(2)無境界ワイルドカード
8.制約と限界
(1)基本データ型でタイプパラメータをインスタンス化できない(2)ランタイムタイプクエリ元のタイプ(3)パラメータタイプを作成できない配列にのみ適用
例:
Pair<String>[] table = new Pair<String> [10]; //error
解決策:*ArrayList
(4)Varargs警告
抑制警告:@SuppressWarnings("unchecked")またはsafe Varargs
(5)タイプ変数をインスタンス化できない(6)汎用クラスの静的コンテキストでタイプ変数が無効(7)汎用クラスのインスタンスを投げ出したり捕獲したりできない(8)消去後の衝突を防ぐ