1.ジェネリックとは何ですか?
ジェネリックインターフェイスのコンセプトは、「汎用」、さらに拡張され、文字通りのタイプの広い範囲を意味します。クラス、インタフェースおよび方法は、コードタイプの非常に広い範囲に適用することができ、データ種別コード、もはや一緒に結合された結合を低減するだけでなく、そのようにコードの再利用、それらの、コードの同じセットは、データの様々なタイプのために使用することができるで動作可能ですが、また、読みやすさとセキュリティコードを向上させます。抽象化の利点を話す、我々は実際の例を見て。
2.ジェネリックの簡単な例を初めて目
package genericity.demo;
/**
* @author BastetCat
* @data 2019/8/8 21:14
*/
public class Pair<T> {
T one;
T two;
public Pair(T one, T two) {
this.one = one;
this.two = two;
}
public T getOne() {
return one;
}
public T getTwo() {
return two;
}
}
観察と通常のクラスの違い:
- 戻る1以上のクラス名
<T>
- 1とタイプ2はTです
T 3.だからそれは何ですか?
T型パラメータを表し
ジェネリック型パラメータであり、データ処理の種類が固定されていませんが、パラメータとして渡すことができます。
今、私たちは、使用するパラメータとしてジェネリック型を知っています。
4.どのようにジェネリック医薬品を使用すると、引数として、それを入力するには?
次のコードは:私たちは、さまざまな種類の型パラメータ(整数、文字、文字列)を渡して、新しい3ペアオブジェクトでした。
package genericity.demo;
/**
* @author BastetCat
* @data 2019/8/8 21:22
*/
public class Test {
public static void main(String[] args) {
Pair<Integer> pairInteger = new Pair<Integer>(1,2);
int one1 = pairInteger.getOne();
int two1 = pairInteger.getTwo();
System.out.println("one:"+one1+",two:"+two1);
Pair<Character> pairCharacter = new Pair<Character>('一','二');
char one2 = pairCharacter.getOne();
char two2 = pairCharacter.getTwo();
System.out.println("one:"+one2+",two:"+two2);
Pair<String> pairString = new Pair<String>("I","II");
String one3 = pairString.getOne();
String two3 = pairString.getTwo();
System.out.println("one:"+one3+",two:"+two3);
}
}
結果は以下の通りであります:
one:1,two:2
one:一,two:二
one:I,two:II
もちろん、私たちはまた、複数の型パラメータを渡すことができ、型パラメータを渡すことはできません。カンマでパラメータの複数種類の「」分離しました。次の例のように:
package genericity.demo;
/**
* @author BastetCat
* @data 2019/8/8 21:37
*/
public class PairTwo <U,V> {
U one;
V two;
public PairTwo(U one, V two) {
this.one = one;
this.two = two;
}
public U getOne() {
return one;
}
public V getTwo() {
return two;
}
}
だから、使用します:
PairTwo<String,Integer> pairTwo = new PairTwo<>("牛牛",20);
注:Java 7の初め以来、パラメータの後ろのサポートの種類を省略、簡素書くようにします。
ジェネリック医薬品の基本原理
最終的にはジェネリック型引数は何ですか?なぜ我々は型パラメータを定義する必要がありますか?一般的なカテゴリを定義し、直接オブジェクトを使用することも可能です。私たちが書くことができる前にとしてペアクラス:
package genericity.demo;
/**
* @author BastetCat
* @data 2019/8/8 21:44
*/
public class PairObject {
Object one;
Object two;
public PairObject(Object one, Object two) {
this.one = one;
this.two = two;
}
public Object getOne() {
return one;
}
public Object getTwo() {
return two;
}
}
そして、このような使用は、効果は同じです。
package genericity.demo;
/**
* @author BastetCat
* @data 2019/8/8 21:46
*/
public class TestPairObject {
public static void main(String[] args) {
PairObject pairObject1 = new PairObject(1,2);
int one1 =(int)pairObject1.getOne();
int two1 =(int)pairObject1.getTwo();
System.out.println("one:"+one1+",two:"+two1);
PairObject pairObject2 = new PairObject("yi","er");
String one2 =(String)pairObject2.getOne();
String two2 =(String)pairObject2.getTwo();
System.out.println("one:"+one2+",two:"+two2);
}
}
出力:
one:1,two:2
one:yi,two:er
我々は確かに私達の使用目的+キャストも同じ結果を得ることがわかります。実際には、私たちのJavaジェネリックの内部原則はケースです。
私たちは、Pair.classとTest.classの結果をコンパイルするためにJADツールを使用して以下のとおりです。
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Pair.java
package genericity.demo;
public class Pair
{
public Pair(Object obj, Object obj1)
{
one = obj;
two = obj1;
}
public Object getOne()
{
return one;
}
public Object getTwo()
{
return two;
}
Object one;
Object two;
}
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Test.java
package genericity.demo;
import java.io.PrintStream;
// Referenced classes of package genericity.demo:
// Pair
public class Test
{
public Test()
{
}
public static void main(String args[])
{
Pair pair = new Pair(Integer.valueOf(1), Integer.valueOf(2));
int i = ((Integer)pair.getOne()).intValue();
int j = ((Integer)pair.getTwo()).intValue();
System.out.println((new StringBuilder()).append("one:").append(i).append(",two:").append(j).toString());
Pair pair1 = new Pair(Character.valueOf('\u4E00'), Character.valueOf('\u4E8C'));
char c = ((Character)pair1.getOne()).charValue();
char c1 = ((Character)pair1.getTwo()).charValue();
System.out.println((new StringBuilder()).append("one:").append(c).append(",two:").append(c1).toString());
Pair pair2 = new Pair("I", "II");
String s = (String)pair2.getOne();
String s1 = (String)pair2.getTwo();
System.out.println((new StringBuilder()).append("one:").append(s).append(",two:").append(s1).toString());
}
}
上記の分析を通して:
私たちは、JavaコンパイラのJavaソースファイルは、バイトコードの.classファイルにロードして実行する仮想マシンをコンパイルされる、ことがわかります。ジェネリッククラスの場合、Javaコンパイラは、従来の非汎用コードに変換します。消去型T、その後、必要なキャストを挿入し、オブジェクトを交換してください。Java仮想マシンの実際の実装は、ジェネリック医薬品は事を知らない場合には、ちょうどその普通のクラスとコードを知っています。
なぜ、このような汎用的な設計をする必要がありますか?
Javaのジェネリックは、わずか5サポートの後に、このような互換性のための設計、および最後の選択肢であるため。
6.ジェネリックの利点を使用します
- コードの再利用:私たちは別のクラスをサポートすることができ、コードを持っています。
- 結合を低減:コードおよび論理データ・タイプ間の分離を、分離を達成します。
- 読みやすくする:我々は、設定した時間を使用し、リストとして定義され
List<String>
、リスト記憶の文字列型という直感的です。 - 高いセキュリティ:重要な目標とプログラミング言語は、クレードルのバグを破壊することで、書面で挟持することができ、実行時に滞在していません。私たちは、定義した場合
List<String>
、このようなリストを。我々は(Eclipseなど)私たちのIDE内部リストへのデータの他の非文字列型を入れたときにエラーを促すメッセージが表示されます。でもノーIDE場合。時間をコンパイルし、Javaコンパイラが呼び出され、要求されますタイプの安全性。これは、プログラムのセキュリティガードを設定します。同様に、ジェネリックの使用はまた、通常のオブジェクトを使用して面倒なキャストを排除します。これとは対照的に、通常のオブジェクトの使用は、プロンプトが表示されない時間をコンパイルして。渡されたパラメータと、最終的なキャストのタイプが矛盾している場合。ClassCastExceptionがジェネリックにはない使用するように、実行されます。