JAva汎用学習ノート
9067 ワード
JAva汎用型はJDK 1.5から出てきて、自分でも普段は役に立ちますが、ずっと全面的に勉強していません.今日はmyibatis 3.0.1ソースコードを見ていると、汎用型のデザインがたくさん使われているのを見て、自分で汎用型を勉強しました.
汎用とは?
Java SE 1.5以前に汎用型がなかった場合、タイプObjectへの参照によってパラメータの「任意化」が実現され、「任意化」による欠点は、Object参照オブジェクトが「アップモールド」され、オブジェクトの具体的なタイプ情報が失われることであり、このタイプを使用する場合に明示的な強制タイプ変換を行うことである.この変換は,開発者が実際のパラメータタイプを予知できる場合に行うことを要求する.強制タイプ変換エラーの場合、コンパイラはエラーを提示せず、実行時に異常が発生する可能性があります.これはセキュリティ上の危険です.
汎用型の利点は、コンパイル時にタイプのセキュリティをチェックし、すべての強制変換が自動的で暗黙的であり、コードの再利用率を向上させることです.
汎用使用のルールと制限
汎用的な基本的な使用
eg 1:汎用型を用いた
package com.kyle.Generics.ch01;
/**
*
* @author kyle
*
* @param <T>
*/
public class SimpleDemo1<T> {
private T ob;//
public T getOb() {
return ob;
}
public void setOb(T ob) {
this.ob = ob;
}
public SimpleDemo1(T ob){
this.ob=ob;
}
public void showType(){
System.out.println("T :"+ob.getClass().getName());
}
public static void main(String args[]){
// SimpleDemo Integer
SimpleDemo1<Integer> intObj=new SimpleDemo1<Integer>(88);
// ob
Integer intValue=intObj.getOb();
intObj.showType();
// SimpleDemo String
SimpleDemo1<String> strObj=new SimpleDemo1<String>("Hello world");
// ob
String strValue=strObj.getOb();
strObj.showType();
String str=strObj.getOb();
System.out.println("ob is vlaue :"+str);
}
}
eg 2:汎用実装は使用されていない
package com.kyle.Generics.ch01;
/**
*
* @author kyle
*
*/
public class SimpleDemo2{
private Object ob; //
public SimpleDemo2(Object ob) {
this.ob = ob;
}
public Object getOb() {
return ob;
}
public void setOb(Object ob) {
this.ob = ob;
}
public void showType(){
System.out.println("Object :"+ob.getClass().getName());
}
public static void main(String args[]){
SimpleDemo2 intObj=new SimpleDemo2(new Integer(88));
int intValue=(Integer)intObj; // Integer
intObj.showType();
SimpleDemo2 strObj=new SimpleDemo2(new String("Hello Gen2"));
String strValue=(String)strObj;// String
strObj.showType();
}
}
上記の2つのDEMOの比較により,汎用性がもたらす使いやすさを直接見ることができる.ここでDEMO 1では,Tがオブジェクトを構築する際に動的に伝達される文字列であると簡単に想定できる.
SimpleDemo 1
汎用的な高度な応用
1.汎用型の使用可能なタイプを制限する
class GenericsFoo
注意:
eg:
package com.kyle.Generics.ch03;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
public class CollectionGenFoo <T extends Collection>{
private T x;
public CollectionGenFoo( T x){
this.x=x;
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public static void main(String args[]){
/**1
* CollectionGenFoo ArrayList
* listFoo
* ArrayList
* new ArrayList() ArrayList
*/
CollectionGenFoo<ArrayList> listFoo = null;
listFoo=new CollectionGenFoo<ArrayList>(new ArrayList());
listFoo.getX();// ArryList
/**2
* CollectionGenFoo Collection
* listFoo
* Collection
* new ArrayList() Collection
* Collection
*/
CollectionGenFoo<Collection> listFoo2 = null;
listFoo2=new CollectionGenFoo<Collection>(new ArrayList());
listFoo2.getX();// Collection
/**3
*
*CollectionGenFoo<String> Collection
*/
//CollectionGenFoo<String> listFoo3=null;
/**4
* , Collection
* new CollectionGenFoo<ArrayList>
* T
*/
//CollectionGenFoo<Collection> listFoo4 = null;
//listFoo4=new CollectionGenFoo<ArrayList>(new ArrayList());
}
}
この例を通して、私たちは1,2,3,4の3つの声明方式をよく比較して、汎用的な意味を体得しなければならない.
1.1,2,3から「有界汎用型」
Bound mismatch: The type String is not a valid substitute for the bounded parameter
2.
2.ワイルドカード汎用
上記の例では、特定の汎用タイプの参照を宣言する場合、対応するインスタンスの汎用タイプは参照の汎用タイプと同じでなければなりません.これにより、複数の汎用タイプのサブクラスインスタンスがある場合、複数の異なる参照、すなわち、参照が具体化され、言い換えれば、汎用タイプが具体化され、だから私たちの引用も具体化されました.では、汎用的な参照を含めるにはどうすればいいのでしょうか.
任意のインスタンスタイプも受け入れられますか?
eg: 上のDEMOを続け、mainメソッドに次の宣言を加えます.
/**5
* CollectionGenFoo<? extends Collection>
* listFoo5 Collection
*
*/
CollectionGenFoo<? extends Collection> listFoo5 = null;
listFoo5=new CollectionGenFoo<ArrayList>(new ArrayList());
listFoo5=new CollectionGenFoo<LinkedList>(new LinkedList());
listFoo5.getX();// Collection
/**
* CollectionGenFoo<?>
* listFoo5 Collection
*
*/
CollectionGenFoo<?> listFoo6 = null;
listFoo6=new CollectionGenFoo<ArrayList>(new ArrayList());
listFoo6=new CollectionGenFoo<LinkedList>(new LinkedList());
listFoo6.getX();// Object
/*
* :
* ? ,
* Collection
*/
/* :
*Bound mismatch: The type String is not a valid substitute for the bounded parameter
*<T extends Collection> of the type CollectionGenFoo<T>
*/
//listFoo6=new CollectionGenFoo<String>(new String("test"));
まとめ:
1.5から、CollectionGenFooのワイルドカード方式でオブジェクト参照を宣言する場合、参照は異なる汎用オブジェクトインスタンスを受け入れることができるが、このインスタンス汎用の具体的なタイプは失われ、すべてSuperClassタイプに遡及される
2.CollectionGenFooのワイルドカード方式でオブジェクト参照を宣言する場合、参照は異なる汎用のオブジェクトインスタンスを受け入れることができるが、そのインスタンスの汎用の具体的なタイプは失われ、すべてObjectタイプに遡及される.
3.5,6の 新例の汎用型は、SuperClassのサブクラスまたはSuperClassのタイプである必要があります.
4.ワイルドカードの汎用型は、下に制限するだけでなく、上に制限することもできます.例えば、は、タイプがArrayListタイプとその上位親タイプしか受け入れられないことを示します.たとえば、List、Collection
3.汎用方法
未完...
汎用設計の使用シーン