ジェネリック
JDK1.5で新たに追加されたジェネリックは、データタイプのセキュリティ問題を解決します。主な原則は、クラス内の属性のタイプ、またはクラス宣言内の識別子を介してメソッドの戻り値とパラメータタイプを示すことです。このように、クラスが宣言またはインスタンス化されるときに、必要な特定のタイプを指定するだけです。
Javaジェネリックは、プログラムがコンパイル時に警告を発行しない場合、実行時にClassCastExceptionを生成しないことを保証できます。同時に、コードはより簡潔で堅牢です。
•Javaのジェネリックは、コンパイル中にのみ有効です。コンパイルプロセスでは、ジェネリックの結果を正しくチェックした後、ジェネリックの関連情報が消去され、メソッドに出入りするオブジェクトの境界にタイプチェックとタイプ変換のメソッドが追加されます。つまり、一般的な情報は実行時フェーズに入りません。
1.オブジェクトがインスタンス化されるとき、ジェネリックタイプは指定されません。デフォルトは、オブジェクトです。
2.異なるジェネリックタイプの参照を相互に割り当てることはできません。
//定义一个泛型接口
interface Generator<T> {
T next();
}
- ジェネリック引数が渡されない場合は、ジェネリッククラスの定義と同じです。クラスを宣言するときは、ジェネリック宣言をクラスに追加する必要があります。
- 即:クラスFruitGeneratorはGeneratorを実装します{
- 次のようなジェネリックを宣言しない場合:クラスFruitGeneratorはGeneratorを実装し、コンパイラはエラーを報告します:「不明なクラス」
*/
class FruitGenerator<T> implements Generator<T>{
@Override
public T next() {
return null;
}
}
/**
- 一般的な引数を渡す場合:
- このインターフェイスを実装するプロデューサーを定義しますが、汎用インターフェイスジェネレーターのみを作成しました
- しかし、Tの無数の実際のパラメーターを渡して、無数のタイプのジェネレーターインターフェイスを形成することができます。
- 実装クラスがジェネリックインターフェイスを実装するときに、ジェネリックタイプが引数タイプに渡されている場合、ジェネリックタイプが使用されるすべての場所を、渡された引数タイプに置き換える必要があります。
- つまり、Generator、public T next(); Tinは着信文字列タイプに置き換える必要があります。
*/
class FruitGenerator implements Generator<String> {
@Override
public String next() {
// TODO Auto-generated method stub
return null;
}
}
ジェネリックメソッドは、その中で定義されているクラスがジェネリックであるかどうかに関係なく、ジェネリックにすることもできます。ジェネリックパラメータはジェネリックメソッドで定義できます。現時点では、パラメータのタイプは受信データのタイプです。
一般的な方法の形式:
public class DAO {
public <E> void show(E e){
System.out.println(e.toString());
}
public <T> T show1(T t){
return t;
}
}
/**
* 泛型方法与可变参数
* @param args
*/
public <T> void printMsg( T... args){
for(T t : args){
System.out.println("泛型测试 ,t is " + t);
}
}
/**
* 静态方法无法访问类上定义的泛型;
* 如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上
* @author lby
* @param <T>
*/
class StaticGenerator<T> {
/**
* 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
* 即使静态方法要使用泛型类中已经声明过的泛型也不可以。
* 如:public static void show(T t){..},此时编译器会提示错误信息:
"StaticGenerator cannot be refrenced from static context"
*/
public static <T> void show(T t){
}
}
ワイルドカード
/**
* 不确定集合中的元素具体的数据类型
* 使用?表示所有类型
* @param list
*/
public void test(List<?> list){
System.out.println(list);
}
例えば:
<?extends Person>(Infinitesimal、Person)PersonおよびPersonサブクラス参照の汎用呼び出しのみを許可<?super Person> [Person、Infinity)PersonおよびPerson親クラスの汎用呼び出しのみを許可<?extends Comparable > Comparableインターフェースを実装する実装クラスへの参照によってのみジェネリックの呼び出しを許可する