十:Javaの汎用型
9545 ワード
【定義】
一、汎用型の定義は主に以下の2種類がある.
プログラム符号化には、タイプパラメータを含むタイプがあります.すなわち、汎用パラメータはクラスのみを表すことができ、個別のオブジェクトを表すことはできません.(これは現在一般的な定義です)
プログラム符号化にパラメータを含むクラスがあります.そのパラメータは、クラスやオブジェクトなどを表すことができます.(現在ではテンプレートと呼ばれることが多い)
その定義を使用するにかかわらず、汎用パラメータは、実際に汎用を使用する場合に指定する必要があります.
汎用クラスは、クラスをインスタンス化する際に汎用の具体的なタイプを示す.
汎用メソッドは、メソッドを呼び出すときに汎用の具体的なタイプを示すメソッドです.
二、汎用型を使用する目的:
いくつかの強いタイプのプログラム言語は汎用型をサポートし、その主な目的はタイプの安全を強化し、クラスの変換回数を減らすことであるが、いくつかの汎用型をサポートするプログラム言語は一部の目的しか達成できない.
汎用プログラミング(Genericprogramming)は、作成されたコードが多くの異なるタイプのオブジェクトで再利用できることを意味する.
Java言語のタイプシステムの拡張であり、タイプ別にパラメータ化できるクラスの作成をサポートします.タイプパラメータは、メソッドの形式パラメータが実行時に渡される価値のあるプレースホルダであるように、パラメータ化タイプを使用するときに指定されたタイプのプレースホルダと見なすことができます.
【Java汎用のいくつかのタイプコード】
一、汎用コードを使用しない
3つの属性x,y,zを含むPersonクラスを定義した.定義を開始すると、この3つの属性が何に使われているのか分からないので、Objectタイプとして定義します.しかし,x,y,zにはint,double,Stringタイプがそれぞれ与えられているので,取り出す際にはこの3つのタイプ値を強制的に変換する必要がある.次のコードがあります.
1. Person.java
二、1つのタイプの変数の汎用的なコードを使用する
汎用クラスPersonを定義し、3つのプロパティx,y,zを定義し、テストクラスでプロパティの値を設定し、印刷します.
四、汎用的な継承を使用する
汎用クラスPersonを定義し、2つの属性x,yを定義し、別の汎用クラスBoyを定義し、属性zを定義し、BoyはPersonクラスを継承し、テストクラスでは属性の値を設定し、印刷します.
五、汎用的なインタフェースの使用
汎用インタフェースPersonを定義し、2つのメソッドを定義し、次に別の汎用クラスBoyを定義し、汎用インタフェースPersonを実現し、属性x,y,zを定義し、テストクラスで属性の値を設定し、印刷します.
六、汎用方法の使用
説明すると、汎用メソッドを定義する場合は、戻り値の前にを付けて、汎用メソッドであることを宣言し、汎用Tを保持してから、汎用Tをメソッドの戻り値として使用することができます.
一般クラスPersonを定義し、次のコードで汎用メソッドを定義します.
七、型変数の限定
次のコードでは、メソッドminで変数smallestタイプをTとして定義します.これは、smallestが任意のクラスのオブジェクトであってもよいことを示しています.次のコードではcompareToメソッドを使用する必要がありますが、TにCompareToメソッドが含まれているとは判断できません.したがって、Tを限定し、コードではTにComparableクラスを継承させる必要があります.次のようになります.
【Java汎用理解】
一、タイプ消去
汎用概念を正しく理解する第一の前提は、タイプ消去を理解することである.(type erasure).Javaにおける汎用は基本的にコンパイラという階層で実現される.生成されたJavaバイトコードには汎用中のタイプ情報は含まれていない.汎用を使用する際に付けられたタイプパラメータは、コンパイラによってコンパイル時に取り除かれる.このプロセスをタイプ消去と呼ぶ.コードで定義されたList
一、汎用型の定義は主に以下の2種類がある.
プログラム符号化には、タイプパラメータを含むタイプがあります.すなわち、汎用パラメータはクラスのみを表すことができ、個別のオブジェクトを表すことはできません.(これは現在一般的な定義です)
プログラム符号化にパラメータを含むクラスがあります.そのパラメータは、クラスやオブジェクトなどを表すことができます.(現在ではテンプレートと呼ばれることが多い)
その定義を使用するにかかわらず、汎用パラメータは、実際に汎用を使用する場合に指定する必要があります.
汎用クラスは、クラスをインスタンス化する際に汎用の具体的なタイプを示す.
汎用メソッドは、メソッドを呼び出すときに汎用の具体的なタイプを示すメソッドです.
二、汎用型を使用する目的:
いくつかの強いタイプのプログラム言語は汎用型をサポートし、その主な目的はタイプの安全を強化し、クラスの変換回数を減らすことであるが、いくつかの汎用型をサポートするプログラム言語は一部の目的しか達成できない.
汎用プログラミング(Genericprogramming)は、作成されたコードが多くの異なるタイプのオブジェクトで再利用できることを意味する.
Java言語のタイプシステムの拡張であり、タイプ別にパラメータ化できるクラスの作成をサポートします.タイプパラメータは、メソッドの形式パラメータが実行時に渡される価値のあるプレースホルダであるように、パラメータ化タイプを使用するときに指定されたタイプのプレースホルダと見なすことができます.
【Java汎用のいくつかのタイプコード】
一、汎用コードを使用しない
3つの属性x,y,zを含むPersonクラスを定義した.定義を開始すると、この3つの属性が何に使われているのか分からないので、Objectタイプとして定義します.しかし,x,y,zにはint,double,Stringタイプがそれぞれ与えられているので,取り出す際にはこの3つのタイプ値を強制的に変換する必要がある.次のコードがあります.
1. Person.java
<span style="font-size:18px;"> public class Person {
private Object x;
private Object y;
private Object z;
// Object 。
public Object getX() {
return x;
}
public void setX(Object x) {
this.x = x;
}
public Object getY() {
return y;
}
public void setY(Object y) {
this.y = y;
}
public Object getZ() {
return z;
}
public void setZ(Object z) {
this.z = z;
}
}
2. NoGenericTest.java
public class NoGenericTest {
public static void main(String[]args){
Person boy=new Person();
boy.setX(20);
boy.setY(22.2);
boy.setZ(" TT");
// , 。
int x=(Integer)boy.getX();
double y=(double)boy.getY();
String z=(String)boy.getZ();
System.out.println(x);
System.out.println(y);
System.out.println(z);
}
}
3.
20
22.2
TT</span>
二、1つのタイプの変数の汎用的なコードを使用する
汎用クラスPersonを定義し、3つのプロパティx,y,zを定義し、テストクラスでプロパティの値を設定し、印刷します.
<span style="font-size:18px;"> 1. Person.java
public class Person<T> {
private T x;
private T y;
private T z;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
public T getZ() {
return z;
}
public void setZ(T z) {
this.z = z;
}
}
2. GenericTest.java
public class GenericTest {
public static void main(String[]args){
Person boy=new Person();
boy.setX(20);
boy.setY(22.2);
boy.setZ(" TT");
//
System.out.println(boy.getX());
System.out.println(boy.getY());
System.out.println(boy.getZ());
}
}
3.
20
22.2
TT
、
Person, x,y, , , , 。
1. Person.java
public class Person<T1,T2> {
private T1 x;
private T2 y;
public T1 getX() {
return x;
}
public void setX(T1 x) {
this.x = x;
}
public T2 getY() {
return y;
}
public void setY(T2 y) {
this.y = y;
}
}
2. GenericTest.java
public class GenerricTest {
public static void main(String[] args){
Person<String,Integer> boy=new Person<String,Integer>();
boy.setX(" TT");
boy.setY(20);
System.out.println(boy.getX());
System.out.println(boy.getY());
}
}
3.
TT
20</span>
四、汎用的な継承を使用する
汎用クラスPersonを定義し、2つの属性x,yを定義し、別の汎用クラスBoyを定義し、属性zを定義し、BoyはPersonクラスを継承し、テストクラスでは属性の値を設定し、印刷します.
1. Person.java
public class Person<T1,T2> {
private T1 x;
private T2 y;
public T1 getX() {
return x;
}
public void setX(T1 x) {
this.x = x;
}
public T2 getY() {
return y;
}
public void setY(T2 y) {
this.y = y;
}
}
2. Boy
public class Boy<T1,T2,T3>extendsPerson<T1,T2> {
private T3 z;
public T3 getZ() {
return z;
}
public void setZ(T3 z) {
this.z = z;
}
}
3. GenericTest.java
1public class GenericTest {
2 public static void main(String[] args){
3 Boy<String,Integer,Double> boy=new Boy<String,Integer,Double>();
4 boy.setX(" TT");
5 boy.setY(20);
6 boy.setZ(200000.22);
7
8 System.out.println(boy.getX());
9 System.out.println(boy.getY());
10 System.out.println(boy.getZ());
11 }
12 }
4.
1 TT
2 20
3 200000.22
五、汎用的なインタフェースの使用
汎用インタフェースPersonを定義し、2つのメソッドを定義し、次に別の汎用クラスBoyを定義し、汎用インタフェースPersonを実現し、属性x,y,zを定義し、テストクラスで属性の値を設定し、印刷します.
<span style="font-size:18px;">1. Person.java
1 public interface Person<T1,T2> {
2 public T1 getX();
3 public T2 getY();
4 }
2. Boy
1public class Boy<T1,T2,T3>implements Person<T1,T2> {
2 private T1 x;
3 private T2 y;
4 private T3 z;
5 public T1 getX() {
6 return x;
7 }
8 public void setX(T1 x) {
9 this.x = x;
10 }
11 public T2 getY() {
12 return y;
13 }
14 public void setY(T2 y) {
15 this.y = y;
16 }
17 public T3 getZ() {
18 return z;
19 }
20 public void setZ(T3 z) {
21 this.z = z;
22 }
23
24 }
3. GenericTest.java
1public class GenericTest {
2 public static void main(String[] args){
3 Boy<String,Integer,Double> boy=newBoy<String,Integer,Double>();
4 boy.setX(" TT");
5 boy.setY(20);
6 boy.setZ(200000.22);
7 System.out.println(boy.getX());
8 System.out.println(boy.getY());
9 System.out.println(boy.getZ());
10 }
11 }
4.
1 TT
2 20
3 200000.22</span>
六、汎用方法の使用
説明すると、汎用メソッドを定義する場合は、戻り値の前に
一般クラスPersonを定義し、次のコードで汎用メソッドを定義します.
<span style="font-size:18px;">1. Person.java
1public class Person{
2 public static<T>T getMiddle(T[]a){
3 return a[a.length/2];
4 }
5 public static void main(String [] args){
6 String[]name={" TT"," TT1"," TT2"};
7 String middle=Person.<String>getMiddle(name);
8 System.out.println(middle);
9
10 Integer[]num={20,22,25};
11 Integer middle1=Person.<Integer>getMiddle(num);
12 System.out.println(middle1);
13
14 Double[]num1={20.0,22.2,25.5};
15 Double middle2=Person.<Double>getMiddle(num1);
16 System.out.println(middle2);
17 }
18 }
2.
1 TT1
2 22
3 22.2</span>
七、型変数の限定
次のコードでは、メソッドminで変数smallestタイプをTとして定義します.これは、smallestが任意のクラスのオブジェクトであってもよいことを示しています.次のコードではcompareToメソッドを使用する必要がありますが、TにCompareToメソッドが含まれているとは判断できません.したがって、Tを限定し、コードではTにComparableクラスを継承させる必要があります.次のようになります.
<span style="font-size:18px;">public static<T extendsComparable>T min(T[]a)
1.Person.java
1public class Person{
2 public static<T extends Comparable>T min(T[]a){
3 if(a==null||a.length==0){
4 return null;
5 }
6 T smallest=a[0];
7 for(int i=1;i<a.length;i++){
8 if(smallest.compareTo(a[i])>0){
9 smallest=a[i];
10 }
11 }
12 return smallest;
13 }
14 public static void main(String [] args){
15 Integer[]num={20,25,30,10};
16 Integer middle=Person.<Integer>min(num);
17 System.out.println(middle);
18 }
19 }
2.
10</span>
【Java汎用理解】
一、タイプ消去
汎用概念を正しく理解する第一の前提は、タイプ消去を理解することである.(type erasure).Javaにおける汎用は基本的にコンパイラという階層で実現される.生成されたJavaバイトコードには汎用中のタイプ情報は含まれていない.汎用を使用する際に付けられたタイプパラメータは、コンパイラによってコンパイル時に取り除かれる.このプロセスをタイプ消去と呼ぶ.コードで定義されたList