A.ジェネリック医薬品の使用
1.概要と、一般的なクラスの使用
- A:概要ジェネリッククラス:で定義されている一般的なクラス
- B:定義フォーマット:クラスのパブリック・クラス名<ジェネリック型1、...>
- C:注:ジェネリック型が参照型である必要があります
2.概要と一般的な方法の使用
- A:一般的な方法の概要:で定義されている一般的な方法
- B:定義フォーマット:パブリック<ジェネリック型>戻り値の型の名前(変数名ジェネリック型)
public <T> void show(T t) {
}
いわゆる一般的な方法は、型宣言の方法で1つまたは複数のパラメータを定義することです。次のように使用形式の一般的な方法は次のとおりです。
修饰符<T, S> 返回值类型 方法名(形参列表){
方法体
}
注意点:
- クラス宣言で定義されたタイプのパラメータインタフェースは、インタフェースクラス全体で使用されてもよい場合の方法で定義されたパラメータの宣言方法にのみ使用することができます。渡された実際の目的に応じて、楽しい()メソッドを呼び出すときに、コンパイラは、実際の型は、型パラメータTで表されることを決定します
class Demo{
public <T> T fun(T t){ // 可以接收任意类型的数据
return t ; // 直接把参数返回
}
};
public class GenericsDemo26{
public static void main(String args[]){
Demo d = new Demo() ; // 实例化Demo对象
String str = d.fun("汤姆") ; // 传递字符串
int i = d.fun(30) ; // 传递数字,自动装箱
System.out.println(str) ; // 输出内容
System.out.println(i) ; // 输出内容
}
};
3.概要と汎用インタフェースの使用
ケースを初めて目
- A:概要の汎用インターフェース:インターフェースはジェネリックで定義されています
- B:定義フォーマット:パブリックインタフェースのインタフェース名<ジェネリック型>
/**
* 泛型接口的定义格式: 修饰符 interface 接口名<数据类型> {}
*/
public interface Inter<T> {
public abstract void show(T t) ;
}
/**
* 子类是泛型类
*/
public class InterImpl<E> implements Inter<E> {
@Override
public void show(E t) {
System.out.println(t);
}
}
Inter<String> inter = new InterImpl<String>() ;
inter.show("hello") ;
次いで、ジェネリックを使用してソースコードを見て、JDK 1.5、リストインターフェイス後未満である、及びコードセグメントは、クラスのArrayList。
//定义接口时指定了一个类型形参,该形参名为E
public interface List<E> extends Collection<E> {
//在该接口里,E可以作为类型使用
public E get(int index) {}
public void add(E e) {}
}
//定义类时指定了一个类型形参,该形参名为E
public class ArrayList<E> extends AbstractList<E> implements List<E> {
//在该类里,E可以作为类型使用
public void set(E e) {
.......................
}
}
これは一般的なの本質である:全体のインターフェイスにインターフェイス、クラス型パラメータ宣言、型パラメータの定義を可能にする、従来のタイプを使用することはほとんどどこにでもとしてインビボで使用されるクラスのタイプは、パラメータのこのタイプを使用することができます。
ジェネリッククラスのサブクラス
- これらのインタフェースは、サブクラス親クラス・タイプ・パラメータを含むことができません。一般的な宣言とのインタフェースを作成した後、親クラスは、親クラスまたはサブクラス、メモから、インターフェース実装クラスのために作成することができます、あなたは、特定のタイプを渡す必要があります。
- 間違った方法:
public class A extends Container<K, V>{}
- 正しい方法:
public class A extends Container<Integer, String>{}
- もし型オブジェクト処理のパラメータとしてV、システムはKであろう、特定の種類を指定しなくてもよいです。次のとおりです。
public class A extends Container{}
4.まとめとジェネリッククラスの使用
キータイプの不確実性のコンテナクラスは、キー値のためのストレージ・キーを定義し、一般的な使用して定義されたKおよびVとして指定することができます
public class Container<K, V> {
private K key;
private V value;
public Container(K k, V v) {
key = k;
value = v;
}
public K getkey() {
return key;
}
public V getValue() {
return value;
}
public void setKey() {
this.key = key;
}
public void setValue() {
this.value = value;
}
}
Containerクラスを使用する場合は、あなただけのさまざまな種類のデータを格納するために使用される異なる論理インスタンスコンテナを作成、特にV缶を入力し、Kを指定する必要が。
public static void main(String[] args) {
Container<String,String> c1=new Container<String ,String>("name","hello");
Container<String,Integer> c2=new Container<String,Integer>("age",22);
Container<Double,Double> c3=new Container<Double,Double>(1.1,1.3);
System.out.println(c1.getKey() + " : " + c1.getValue());
System.out.println(c2.getKey() + " : " + c2.getValue());
System.out.println(c3.getKey() + " : " + c3.getValue());
}
JDK 1.7では、一般的な「ダイヤモンド」構文が追加されます:Javaは限り与えられた角括弧が(<>)、Javaが推測できるかぎ括弧があるべきことができて、ベルトを必要としない工事完了後の一般的な情報を許可どのような一般的な情報。次のとおりです。
Container<String,String> c1=new Container<>("name","hello");
Container<String,Integer> c2=new Container<>("age",22);
一般的なコンストラクタの概要
- 方法としてメソッドシグネチャに宣言ジェネリック型パラメータを可能にするように、Java(登録商標)はまた、いわゆる一般的なコンストラクタを作成し、コンストラクタシグネチャにおける型パラメータの宣言を可能にします。
- そして、一般的な汎用的な方法として区別は、一般的なパラメータを使用していない明示的に指定されたパラメータが渡された場合には、パラメータの型に明示的に指定された場所の対象を明示的に指定されている場合、他のは暗黙的に推論されますタイプと一致していない引数の型を指定すると、エラーをコンパイルします。
public class Person { public <T> Person(T t) { System.out.println(t); } }
- 使い方
public static void main(String[] args){ //隐式 new Person(22); //显示 new<String> Person("hello"); }
ここだけの特別なノートでは、この次のとおりです。
一般的なコンストラクタを明示的にコンストラクタで、ダイヤモンドを使用する必要があります(独自の型パラメータを指定することができますので:クラスの場合は、一般的なコンストラクタを使用する方法の一般的なクラスでありながら、コンストラクタは、一般的なコンストラクタである場合デバイス)、およびそのジェネリッククラスの前にもまた、特定の使用は、ここにまとめるためにいくつかの小さな問題があるでしょうダイヤモンド、の2に登場コンストラクタ)、後のダイヤモンドに(型引数を指定する必要があります。
以下の例の代表
public class Person<E> {
public <T> Person(T t) {
System.out.println(t);
}
}
この使用法:人<文字列> =新しい<整数>人<>(15);この構文が許可されていない、それは直接コンパイルエラーになります!
ジェネリック医薬品のワイルドカードのII。ハイ
1.なぜ使用ワイルドカード
ワイルドカードなジェネリック医薬品の使用のようないくつかのシナリオを、設計、ファーストクラスの動物を宣言し、クラスキャットAnimalクラスの継承を宣言し、明らかに猫動物のクラスは、クラスのサブクラスではなく、リストのリストでありますサブタイプが、多くの場合、我々はプログラムロジックでこれを表現する必要があります。新しいワイルドカードの使用法のジェネリック型パラメータに基づいて、この類似のシーンに対処するために。
2. <?拡張T>上限ワイルドカード
上限ワイルドカード名は<?Tが延びる>野生はTまたはサブクラスであってもよいタイプのパラメータ[自体]になる上部タイプの結合を表し、暗示します。
- どのような特定の種類を判断できないので、アプローチを追加します(nullは任意の型を意味するので、あなたは、ヌルを追加することができます)制限されますが、親の型にリストから要素を取得した後に割り当てることができます。一覧リスト及びリストサブタイプ<?動物を拡張>ため、上図の第1の例として、第三の追加()アクションは、制限されます。
它表示集合中的所有元素都是Animal类型或者其子类
List<? extends Animal>
これは、ワイルドカードの上限と呼ばれ、キーワードのみ引数はリア型サブクラスであるか、またはそれ自体を拡張する指定された型のインスタンス化の際に、達成延びています。
- 例えば:
- 少なくとも、特定の不確実性の種類が、その親を知っているが、これは、コレクション内の要素の種類を決定します。そして、他の操作。
//Cat是其子类
List<? extends Animal> list = new ArrayList<Cat>();
3. <?スーパーT>下限ワイルドカード
下部には、オブジェクトまで、パラメータ化された型は、(それ自体を含む)Tのスーパータイプである第一の層を表し、<スーパーT?>ワイルドカード結合しました
- コンパイラは、このように取得されたオブジェクトの種類のget()戻り値を決定することはできません()メソッドが制限されます。add()メソッド、add()メソッドとタイプTは、第一アド猫型オブジェクトの第2の例として、タイプTのサブタイプを追加することができ、オブジェクトは、次に猫サブクラスの二種類が追加されてもよい、そのこの方法は可能ですが、タイプの動物、明らかに継承関係の後方のオブジェクトを追加した場合、現実的ではありません。
它表示集合中的所有元素都是Cat类型或者其父类
List <? super Cat>
これをインスタンス化する場合、superキーワードを達成するために、ワイルドカードの下限と呼ばれ、型引数はそれ自体のみを入力するか、サブクラスを拡張する指定。
例えば:
//Shape是其父类
List<? super Cat> list = new ArrayList<Animal>();
4. <?> ***ワイルドカード
- いずれのタイプではなく、明示的であれば、そのオブジェクトだけでなく、Javaクラスのいずれかの
- <?>サイードは?のみヌルのいずれかのタイプを表すことができますタイプのいずれかの種類を表します(オブジェクト自体はタイプとみなすことができる、ではなく、あらゆるタイプの代わりに、リストおよびリストそう***ワイルドカードの使用意味は後者のタイプが全く不明であるが、前者のタイプ)は、継承ツリーの最上部であるオブジェクト、で異なっています。
III。のみを使用し、一般的な参照型
渡されなければならないジェネリック型パラメータ参照型のクラスのインスタンスを宣言するときは、基本的な型を使用することはできません
- たとえば、ユーザージェネリッククラスに、次の文は違法です
User<int,double> user=new User<>(1,10,0);
解決方法
- あなたは問題を解決するために、ラッパーの種類を使用することができます