# æ³å
æ³åæ¯ä¸ç§å¨å®ç°åæ°åç±»åçåè½ãåæ°åç±»åå
许ç¼åçµæ´»ä¸å¯éå¤ä½¿ç¨ç代ç ï¼å䏿®µä»£ç è½å¤æä½å¤ç§ç±»åï¼åæ¶ä¿æä¸¥æ ¼çç±»åå®å
¨ã
卿²¡ææ³åçæ
åµä¸ï¼ç¼ç¨è¯è¨å¯è½åªè½ä½¿ç¨ç¹å®ç±»åæé常宽æ³çç±»åï¼ä¾å¦ Object ç±»åï¼ãè¿æ ·åå°±æå³ççºç²äºç±»åå®å
¨ï¼æè
éè¦ç¼å大éçä»£ç æ¥å¤çæ¯ä¸ç§å¯è½çæ°æ®ç±»åã
æ³åå
许å¨å®ä¹ç±»ãæ¥å£åæ¹æ³æ¶ä½¿ç¨ç±»ååæ°ãè¿æ ·çéåãæ°æ®ç»æï¼å段ï¼åç®æ³ï¼æ¹æ³ï¼å¯ä»¥ç¼åæè½å¤ä»¥åæ ·çæ¹å¼å·¥ä½å¨ä¸åçæ°æ®ç±»åä¸ï¼æ é为æ¯ç§æ°æ®ç±»åé½ç¼å代ç ãè¿äºç±»ååæ°å¨å®ä¾åç±»ãè°ç¨æ¹æ³æå®ç°æ¥å£æ¶è¢«å
·ä½çç±»åææ¿æ¢ã
## æ³åçä½ç¨
- **ç±»åå®å
¨** æ³åæä¾äºå¢å çç±»åæ£æ¥ï¼å
许å¨ç¼è¯æ¶ææè·å°éæ³çç±»åãä½¿ç¨æ³åå¯ä»¥ç¡®ä¿åªæç¬¦åç¹å®ç±»ååæ°ç对象被æå
¥å°éåä¸ï¼åå°è¿è¡æ¶åºç°`ClassCastException`çå¯è½æ§ã
- **æ¶é¤ç±»å强å¶è½¬æ¢** å¨ä½¿ç¨æ³å容å¨åå¨å¯¹è±¡æ¶ï¼ä¸éè¦å¼ºå¶ç±»å转æ¢å°±è½å¤ååºå
ç´ ãä¾å¦ï¼`List` ä¼ä¿è¯å
¶å
ç´ é½æ¯Â `String` 类åï¼å æ¤åå
ç´ æ¶ä¸åéè¦å°Â `Object` 类å转æ¢ä¸ºÂ `String` 类åã
- **代ç éç¨** æ³å使å¾ç¸åç代ç è½å¤ç¨äºå¤ç§æ°æ®ç±»åãæ³åç±»ãæ¥å£åæ¹æ³æä¸ºå¯ä»¥å·¥ä½å¨å¤ç§æ°æ®ç±»åä¸ç模æ¿ï¼ä»èé¿å
äºä¸ºæ¯ä¸ªæ°æ®ç±»åç¼åéå¤ç代ç ã
## æ³åç±»
æ³åç±»ç¨äºå®ç°ç±»çåæ°åï¼è¿æ ·çç±»è¢«ç§°ä¸ºåæ°åç±»ï¼parameterized classesï¼æè
åæ°åç±»åï¼parameterized typesï¼ããæ³å类使å¾ç±»å¨è¢«å建æ¶è½å¤æå®å
·ä½çç±»ååæ°ï¼è¿å¢å¼ºäºç±»ççµæ´»æ§åå¤ç¨æ§ï¼åæ¶ä¿æäºä»£ç çç±»åå®å
¨æ§ã
æ³åç±»çå®ä¹ç±»ä¼¼äºéæ³åç±»ï¼ä½æ¯å¨ç±»åå颿·»å äºç±»ååæ°é¨åãç±»ååæ°ä½¿ç¨å°æ¬å·<> æ è®°ï¼å¹¶å®ä¹ä¸ºä¸æå¤ä¸ªç±»ååéï¼å¦``ã``çãç±»ååéå¯ä»¥å¨ç±»å®ä¹ä¸çå ä¹ä»»ä½å°æ¹ä½¿ç¨ï¼æ¯å¦ä½ä¸ºå段类åãæ¹æ³åæ°ç±»åãæ¹æ³è¿åç±»åæå±é¨åéç±»åã
å½åå»ºè¿æ ·ä¸ä¸ªç±»çå®ä¾æ¶ï¼ä½ éè¦æå®ç¸åºçå
·ä½ç±»åæ¥ä»£æ¿è¿äºæ³åç±»ååæ°ãè¿æ ·ï¼åä¸ä¸ªç±»çä¸åå®ä¾å¯ä»¥ç¨ä¸åçç±»åæ¥æä½ï¼èä¸éè¦ä¸ºæ¯ç§ç±»åé½åä¸ä¸ªç¹å®çç±»ã
### è¯æ³
```java
public class Box {
private T t;
}
```
- **Box** ä¸ä¸ªæ³åç±»ã
- **T** ä¼ éç»æ³åç±»çç±»ååæ°ãå®å¯ä»¥æ¥åä»»ä½å¯¹è±¡ã
- **t** æ³åç±»å T çå®ä¾ã
### 说æ
T æ¯ä¼ éç»æ³åç±» Box çç±»ååæ°ï¼åºå¨å建 Box 对象æ¶ä¼ éã
### 示ä¾
```java
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box();
Box stringBox = new Box();
integerBox.add(10);
stringBox.add(new String("Hello World"));
System.out.printf("Integer Value: %d\n", integerBox.get());
System.out.printf("String Value: %s\n", stringBox.get());
}
}
class Box {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
```
### è¾åº
```log
Integer Value: 10
String Value: Hello World
```
## å½åè§è
å¨ä½¿ç¨æ³åå®ä¹ç±»ãæ¥å£ææ¹æ³æ¶ï¼ç±»å忰叏叏ç¨å个大å忝æ¥è¡¨ç¤ºï¼è¿ä¸ªæ¯ä¾è½ç¶ä¸æ¯å¼ºå¶æ§çï¼ä½éµå¾ªå®å¯ä»¥è®©ä»£ç æ´æ¸
æ°ï¼ä¹æ´ç¬¦åJavaç¼ç¨ç¤¾åºçä¹ æ¯ã以䏿¯ä¸äºå¸¸è§çæ³åç±»ååæ°å½åè§èï¼
- **E** - Elementï¼å
ç´ ï¼ï¼å¹¿æ³ç¨äºéåä¸çå
ç´ ï¼å¦Â `java.util.List`ã`java.util.Set`çã
- **K** - Keyï¼é®ï¼ï¼ç¨äºæ å°çé®ï¼å¨Â `java.util.Map` ä¸ä½¿ç¨ã
- **V** - Valueï¼å¼ï¼ï¼ç¨äºæ å°çå¼ï¼å¨Â `java.util.Map` ä¸ä½¿ç¨ã
- **T** - Typeï¼ç±»åï¼ï¼è¡¨ç¤ºä¸ä¸ªéç¨çç±»åï¼å½æ²¡ææ´å
·ä½çå«ä¹æ¶ä½¿ç¨ï¼ä¾å¦Â `Box`ã
- **S, U, V** ç - 第äºã第ä¸ã第å个声æçç±»ååæ°ï¼é叏彿å¤ä¸ªç±»ååæ°æ¶ä½¿ç¨ã
- **N** - Numberï¼æ°åï¼ï¼ç¨äºæ°å¼ç±»åçæ³åã
ä¸è¬æ¥è¯´ï¼ç±»ååæ°æå¥½è½å¤åæ åºæç§å«ä¹æçº¦å®ï¼ä½¿å¾ä»£ç å¯ä»¥æ´å®¹æçè§£ãè½ç¶å¯ä»¥ä½¿ç¨ä»»æçç±»ååæ°åç§°ï¼ä½æå¥½é¿å
使ç¨å®¹æä¸å®é
çç±»åææ¥å£åç¸æ··æ·çåç§°ï¼è¿æ ·å¯ä»¥åå°è¯¯è§£ãéµå¾ªä¸è¿°è§èæå©äºä»£ç çé
读åç»´æ¤ã
å¨å®é
ç¼ç¨ä¸ï¼å°¤å
¶æ¯ç¼åæ³åæ¶ï¼éå¸¸ä¼æææ¡£ææ³¨éæ¥è¯´æè¿äºæ³ååæ°çå
·ä½æä¹ï¼ä»¥ä¾¿ä½¿ç¨è
è½å¤æ´å ç´è§å°çè§£å®ä»¬çç¨éã
### 示ä¾
```java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GenericsTester {
public static void main(String[] args) {
Box box = new Box();
box.add(10, "Hello World");
System.out.printf("Integer Value :%d\n", box.getFirst());
System.out.printf("String Value :%s\n", box.getSecond());
Pair pair = new Pair();
pair.add("One", 1);
System.out.println("Pair Integer Value: " + pair.getValue("One"));
CustomList> customList = new CustomList<>();
customList.addItem(box);
System.out.printf("CustomList Value :%d\n", customList.getItem(0).getFirst());
}
}
class Box {
private T t;
private S s;
public void add(T t, S s) {
this.t = t;
this.s = s;
}
public T getFirst() {
return t;
}
public S getSecond() {
return s;
}
}
class Pair {
private Map map = new HashMap();
public void add(K key, V value) {
map.put(key, value);
}
public V getValue(K key) {
return map.get(key);
}
}
class CustomList {
private List list = new ArrayList();
public void addItem(E value) {
list.add(value);
}
public E getItem(int index) {
return list.get(index);
}
}
```
### è¾åº
```log
Integer Value: 10
String Value: Hello World
Pair Integer Value: 1
CustomList Value: 10
```
## ç±»åæ¨æ
ç±»åæ¨æä»£è¡¨Javaç¼è¯å¨æ¥çæ¹æ³è°ç¨åå
¶ç¸åºå£°æçè½åï¼ç¨äºæ£æ¥å¹¶ç¡®å®ç±»ååæ°ãç±»åæ¨æç®æ³ä¼æ£æ¥åæ°çç±»åï¼å¹¶ä¸å¦æå¯è½ï¼è¿ååé
çç±»åãæ¨æç®æ³å°è¯æ¾å°ä¸ä¸ªç¹å®çç±»åï¼è¿ä¸ªç±»åå¯ä»¥æ»¡è¶³ææçç±»ååæ°ã
妿ä¸ä½¿ç¨ç±»åæ¨æï¼ç¼è¯å¨ä¼çææªç»æ£æ¥ç转æ¢è¦åã
### è¯æ³
```java
Box integerBox = new Box<>();
```
- Box ä¸ä¸ªæ³åç±»ã
- <> è±å½¢è¿ç®ç¬¦è¡¨ç¤ºç±»åæ¨æã
使ç¨è±å½¢è¿ç®ç¬¦ï¼ç¼è¯å¨ç¡®å®åæ°çç±»åã该è¿ç®ç¬¦ä» Java SE 7 çæ¬å¼å§å¯ç¨ã
### 示ä¾
```java
public class GenericsTester {
public static void main(String[] args) {
// type inference
Box integerBox = new Box<>();
integerBox.add(10);
// unchecked conversion warning
Box stringBox = new Box();
stringBox.add("Hello World");
System.out.printf("Integer Value: %d\n", integerBox.get());
System.out.printf("String Value: %s\n", stringBox.get());
}
}
class Box {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
```
### è¾åº
```log
Integer Value: 10
String Value: Hello World
```
## æ³åæ¹æ³
æ³åæ¹æ³æ¯æå¨æ¹æ³ä¸å¼å
¥ç±»ååæ°ï¼ä»è使å¾è¯¥æ¹æ³è½å¤çµæ´»å°æ¥åå¤ç§æ°æ®ç±»åçåæ°ãä¸åäºæ³åç±»ï¼æ³åæ¹æ³å
è®¸å¨æ¹æ³çº§å«å£°æç±»ååæ°ï¼è¿äºç±»ååæ°å¨è°ç¨æ¹æ³æ¶ç¡®å®å
·ä½çç±»åãæ³åæ¹æ³å¯ä»¥ç¬ç«äºç±»å®ä¹ï¼å³å®ä»¬å¯ä»¥å¨éæ³åç±»ä¸å®ä¹ï¼ä¹å¯ä»¥å¨æ³åç±»ä¸å®ä¹ã
### 示ä¾
```java
public class GenericMethodTest {
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3, 4, 5};
Double[] doubleArray = {1.1, 2.2, 3.3, 4.4};
Character[] charArray = {'H', 'E', 'L', 'L', 'O'};
System.out.println("Array integerArray contains:");
printArray(intArray);
System.out.println("Array doubleArray contains:");
printArray(doubleArray);
System.out.println("Array charArray contains:");
printArray(charArray);
}
public static void printArray(T[] array) {
for (T element : array) {
System.out.printf("%s ", element);
}
System.out.println();
}
}
```
### è¾åº
```log
Array integerArray contains:
1 2 3 4 5
Array doubleArray contains:
1.1 2.2 3.3 4.4
Array charArray contains:
H E L L O
```
## åå§ç±»å
åå§ç±»åï¼Raw Typeï¼æ¯ææ²¡ææå®æ³åç±»ååæ°çæ³åç±»ææ¥å£ãç®è¨ä¹ï¼åå§ç±»åå°±æ¯å¨ç±»åä¹å没æå°æ¬å·åç±»ååæ°çç±»åãå®ä»¬å¨æ³åå¼å
¥å° Java è¯è¨ï¼Java 5ï¼ä¹åå°±åå¨ï¼ä¸ºäºå
¼å®¹æ§èä¿ç䏿¥ã
åå§ç±»å忽ç¥äºæ³åçç±»ååæ°ï¼å¹¶è§æ³åç±»ææ¥å£ä¸ºéåæ°åçç¶æï¼å
¶è¡ä¸ºç±»ä¼¼äºææçæ³åç±»åä¿¡æ¯é½è¢«æ¦é¤åçç±»åãè¿å°±æå³ç使ç¨åå§ç±»åä¼å¤±å»æ³å带æ¥çç±»åå®å
¨æ§ï¼å 为åå§ç±»åçåéå¯ä»¥æ¥åä»»ä½ç±»åç对象ï¼èä¸åéäºæ³å声æçç±»ååæ°ã
使ç¨åå§ç±»åæ¯ä¸æ¨èçåæ³ï¼å 为å®ä»¬ä¼ä½¿å¾ä½ 失廿³åçä¼å¿ï¼ä¾å¦ç¼è¯æ¶çç±»åæ£æ¥ãåå§ç±»åé常å¨ä»¥ä¸ä¸¤ç§æ
æ¯ä¸åºç°ï¼
*为äºååå
¼å®¹**ï¼æ©æç Java 代ç 卿³åå å
¥ Java ä¹å就已ç»åå¨ï¼è¿äºä»£ç 使ç¨äºåå§ç±»åã为äºå
¼å®¹è¿äºæ§ä»£ç ï¼Java 设计æ³åæ¶ä¿çäºåå§ç±»åç使ç¨ã
**ç±»åä¸æç¡®**ï¼å¨æäºæ
åµä¸ï¼å¯è½ä¸æ¸
æ¥æä¸å
³å¿å
·ä½çæ³åç±»åï¼æè
å 为ç¹å®çåå éè¦ä½¿ç¨åå§ç±»åï¼å°½ç®¡å¨å¤§å¤æ°æ
åµä¸ï¼è¿å¯è½è¡¨æè®¾è®¡ä¸çé®é¢ã
### 示ä¾
```java
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box<>();
integerBox.set(10);
System.out.printf("Integer Value :%d\n", integerBox.get());
// è¦åï¼æªç»æ£æ¥ç转æ¢
Box rawBox = new Box();
// 没æè¦å
rawBox = integerBox;
System.out.printf("Integer Value :%d\n", rawBox.get());
// è¦åï¼æªç»æ£æ¥çè°ç¨set(T)
rawBox.set(20);
System.out.printf("Integer Value :%d\n", rawBox.get());
// éè¦å¼ºå¶ç±»å转æ¢
Integer value = (Integer) rawBox.get();
// è¦åï¼æªç»æ£æ¥ç转æ¢
integerBox = rawBox;
System.out.printf("Integer Value :%d\n", integerBox.get());
}
}
class Box {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
```
### è¾åº
```log
Integer Value: 10
Integer Value: 10
Integer Value: 10
Integer Value: 10
```
## æçç±»ååæ°
æçç±»ååæ°ï¼Bounded Type Parametersï¼æ¯ä¸ç§ä½¿å¾ç±»ååæ°ï¼Type Parametersï¼åå°ä¸å®çº¦æçæºå¶ãæçç±»ååæ°ä½¿å¾å¯ä»¥éå¶å°ç¨äºç¹å®æ³åç±»ãæ¥å£ææ¹æ³çç±»ååæ°çèå´ãè¿é常æ¯éè¿ç»§æ¿ï¼extendsï¼ä¸å®çç±»æå®ç°ï¼implementsï¼æäºæ¥å£æ¥å®ç°çã
### 示ä¾
```java
public class MaximumTest {
public static void main(String[] args) {
System.out.printf("Max of %d, %d and %d is %d\n\n",
3, 4, 5, maximum(3, 4, 5));
System.out.printf("Max of %.1f,%.1f and %.1f is %.1f\n\n",
6.6, 8.8, 7.7, maximum(6.6, 8.8, 7.7));
System.out.printf("Max of %s, %s and %s is %s\n",
"pear", "apple", "orange", maximum("pear", "apple", "orange"));
}
public static > T maximum(T x, T y, T z) {
T max = x;
if (y.compareTo(max) > 0) {
max = y;
}
if (z.compareTo(max) > 0) {
max = z;
}
return max;
}
}
```
卿¤ä¾ä¸ï¼`>` é¨åæå®äº T ç±»åå¿
é¡»å®ç° Comparable æ¥å£ï¼è¿æ ·å¨æ¹æ³å
é¨å¯ä»¥å®å
¨å°è°ç¨ T ç±»å对象ç compareTo æ¹æ³ã
### è¾åº
```log
Max of 3, 4 and 5 is 5
Max of 6.6,8.8 and 7.7 is 8.8
Max of pear, apple and orange is pear
```
## å¤ééå¶
### è¯æ³
```java
public static > T maximum(T x, T y, T z)
```
- *maximum* ä¸ä¸ªæ³åæ¹æ³ã
- *T* ä¼ éç»æ³åæ¹æ³çæ³åç±»ååæ°ãå®å¯ä»¥æ¥åä»»ä½å¯¹è±¡ã
T æ¯ä¼ éç»æ³åç±» Box çç±»ååæ°ï¼åºè¯¥æ¯ Number ç±»çåç±»åï¼å¹¶ä¸å¿
é¡»å®ç° Comparable æ¥å£ãå¦æç±»ä½ä¸ºç»å®ä¼ éï¼ååºå¨æ¥å£ä¹åï¼å¦åä¼åçç¼è¯æ¶é误ã
### 示ä¾
```java
public class MultipleBounds {
public static void main(String[] args) {
System.out.printf("Max of %d, %d and %d is %d\n\n",
3, 4, 5, maximum(3, 4, 5));
System.out.printf("Max of %.1f,%.1f and %.1f is %.1f\n\n",
6.6, 8.8, 7.7, maximum(6.6, 8.8, 7.7));
// The following code will not compile because the String class does not implement the Comparable interface.
/*System.out.printf("Max of %s, %s and %s is %s\n",
"pear", "apple", "orange", maximum("pear", "apple", "orange"));*/
}
public static > T maximum(T x, T y, T z) {
T max = x;
if (y.compareTo(max) > 0) {
max = y;
}
if (z.compareTo(max) > 0) {
max = z;
}
return max;
}
// The following code will not compile
// because the Number class must be the first class in the list of bounds.
/*public static & Number> T maximum(T x, T y, T z) {
T max = x;
if (y.compareTo(max) > 0) {
max = y;
}
if (z.compareTo(max) > 0) {
max = z;
}
return max;
}*/
}
```
### è¾åº
```log
Max of 3, 4 and 5 is 5
Max of 6.6,8.8 and 7.7 is 8.8
```
## éé
符
éé
符æ¯ç¨æ¥è¡¨ç¤ºæªç¥ç±»åçä¸ç§ç¹æ®ç¬¦å·ãéé
ç¬¦å¨æ³å代ç ç¼åä¸åå常è§ï¼é常æ¯ç¨ä¸ä¸ªé®å·Â `?` 代表ã使ç¨éé
符å¯ä»¥æé«ä»£ç ççµæ´»æ§ï¼å
许ç¼ååºæ´å éç¨ç代ç ãJava ä¸çéé
ç¬¦ä¸»è¦æä¸ç§å½¢å¼ï¼æ çéé
符ï¼Unbounded Wildcardï¼ãæçéé
符ï¼å为ä¸çéé
符ï¼Upper Bounded Wildcardï¼åä¸çéé
符ï¼Lower Bounded Wildcardï¼ã
使ç¨éé
符ç主è¦ç®çæ¯ç¼åæ´å çµæ´»ç代ç ï¼ç¹å«æ¯å¨ä½ ç代ç éè¦å
¼å®¹å¤ç§ç±»åçæ¶åãå¨éé
符使ç¨è¿ç¨ä¸è¦è°¨æ
çä¸ç¹æ¯ï¼å¸¦éé
ç¬¦çæ³å对象é常ä¸è½å®å
¨å°åå
¥æ°æ®ï¼å 为å
·ä½çç±»åæªç¥ã
å¨API设计ä¸ï¼é常éµå¾ª"PECS"ååï¼Producer Extends, Consumer Superï¼ï¼æææ¯å¦æè¦ä»éåä¸è¯»åç±»åï¼å³ä½ä¸ºæ°æ®çç产è
ï¼ï¼é£ä¹ä½¿ç¨ä¸çéé
符`extends`ï¼å¦æä½ è¦åå
¥æ°æ®å°éåä¸ï¼å³ä½ä¸ºæ°æ®çæ¶è´¹è
ï¼ï¼é£ä¹ä½¿ç¨ä¸çéé
符`super`ãè¿ä¸ªååæå©äºè®°ä½ä½æ¶ä½¿ç¨ä¸çåä¸çéé
ç¬¦æ¥æé«ä»£ç ççµæ´»æ§åç±»åå®å
¨ã
- **æ çéé
符ï¼Unbounded Wildcardï¼** ç¨ä¸ä¸ªé®å·Â `?` 代表ã
- **ä¸çéé
符ï¼Upper Bounded Wildcardï¼** 使ç¨å
³é®å `extends` æ¥è¡¨ç¤ºã
- **ä¸çéé
符ï¼Lower Bounded Wildcardsï¼** 使ç¨å
³é®å `super`Â æ¥æå®ç±»åçä¸çã
## ä¸çéé
符ï¼Upper Bounded Wildcardsï¼
ä¸çéé
ç¬¦æ¯ Java æ³åä¸çä¸ä¸ªç¹æ§ï¼ç¨æ¥éå¶æ³åç±»åçä¸éï¼å³æ³åç±»ååæ°å¿
é¡»æ¯æä¸ªæå®ç±»çåç±»åï¼å
æ¬è¯¥ç±»åæ¬èº«ï¼ãå¨ Java ä¸ï¼ä¸çéé
符使ç¨å
³é®å `extends` æ¥è¡¨ç¤ºã
ä¸çéé
符é常ä¸éé
符ï¼wildcardï¼`?` ç»å使ç¨ï¼å½¢æäºè¿æ ·çå½¢å¼ï¼`? extends Type`ï¼è¡¨ç¤ºå¯ä»¥æ¥å Type ç±»åæè
å
¶ä»»ä½åç±»åç对象ãä¸çéé
符é常æç¨ï¼å°¤å
¶æ¯å¨å®ä¹æ³åæ¹æ³æè
æ³åç±»åçæ¶åï¼å½ä½ æ³è¦å¯¹è¾å
¥æè¾åºçç±»åæ½å ä¸é约æã
使ç¨ä¸çéé
符ç好夿¯å®å¢å äºæ³åççµæ´»æ§ãå®å¯ä»¥ä½¿ä½ çæ³å代ç è½ç¨äºæ´å¹¿æ³çç±»åèå´ï¼åæ¶ä»ç¶ä¿æç±»åå®å
¨ãå¨è¯»åæä½ï¼å¦è¿ä»£ï¼ä¸ä½¿ç¨ä¸çéé
符æ¯å¾å¸¸è§çï¼å 为å®è½å¤ç¡®ä¿éåä¸å
ç´ çç±»å齿¯æä¸ªç¹å®ç±»çå®ä¾ææ´¾çãç¶èï¼éè¦æ³¨æçæ¯ï¼å½ä½¿ç¨å¸¦æä¸çéé
ç¬¦çæ³åç±»åæ¶ï¼é常ä¸è½åå
¶ä¸åå
¥ä»»ä½å
·ä½çç±»åï¼å 为Javaç¼è¯å¨æ æ³ç¡®å®å®é
æ¥åçç±»åæ¯ä»ä¹ã
### 示ä¾
```java
public class GenericsTester {
public static void main(String[] args) {
List intList = Arrays.asList(1, 2, 3);
System.out.println("Sum of integers: " + sum(intList));
List doubleList = Arrays.asList(1.2, 2.3, 3.5);
System.out.println("Sum of doubles: " + sum(doubleList));
}
public static double sum(List extends Number> list) {
double sum = 0.0;
for (Number i : list) {
sum += i.doubleValue();
}
return sum;
}
}
```
### è¾åº
```log
Sum of integers: 6.0
Sum of doubles: 7.0
```
## æ çéé
符
æ çéé
符ï¼Unbounded Wildcardï¼å®ä¸å¯¹ç±»ååæ°åä»»ä½éå¶ï¼å³Â `?` 代表"ä»»æç±»å"ã
ç¶èï¼ä½¿ç¨æ çéé
ç¬¦ä¹æéå¶ï¼
- å½ä½¿ç¨æ çéé
符æ¶ï¼é¤äºÂ `null` ä¸è½åå
¶åå
¥ä»»ä½ä»¥å¤çå¼ãå 为 Java ç¼è¯å¨æ æ³ç¡®è®¤å®¹å¨ä¸åºè¯¥æ¾ç½®ä½ç§ç±»åç对象ã
- ä½ å¯ä»¥ä»ä½¿ç¨æ çéé
ç¬¦çæ³å容å¨ä¸è¯»åæ°æ®ï¼ä½æ¯ææè¯»ååºæ¥çæ°æ®å°è¢«è§ä¸ºÂ `Object` 类åï¼å 为 `Object`Â æ¯ææ Java ç±»çæç»ç¶ç±»ã
### 示ä¾
```java
public class GenericsTester {
public static void main(String[] args) {
List intList = Arrays.asList(1, 2, 3);
printList(intList);
List doubleList = Arrays.asList(1.2, 2.3, 3.5);
printList(doubleList);
}
public static void printList(List> list) {
for (Object elem : list) {
System.out.print(elem + " ");
}
System.out.prin
```
æ»ç»èµ·æ¥ï¼æ çéé
符çå
³é®ç¹ç¹æ¯å®æä¾å¯¹ä»»ä½ç±»åçæ³å对象ç读åè®¿é®æï¼ä½å¯¹åå
¥æä½å 以éå¶ï¼é¤éåå
¥Â `null`ï¼ãè¿ç§éé
符éç¨äºæ°æ®çä¸åè¡ä¸ºï¼å¦åªè¯»æä½ãå½ä½ ç代ç ä¸éè¦å
³å¿æ³å对象å
·ä½ç±»åæ¶ï¼æ çéé
符æ¯ä¸ç§ç®åææçæ³åç±»å表示æ¹å¼ã
## ä¸çéé
符ï¼Lower Bounded Wildcardsï¼
ä¸çéé
符使ç¨å
³é®å `super`Â æ¥æå®ç±»åçä¸çãä¸çéé
ç¬¦è¡¨ææ³åç±»ååæ°å¿
é¡»æ¯æå®ç±»åçç¶ç±»åï¼å
æ¬è¯¥ç±»åæ¬èº«ï¼ãå¨è¡¨è¾¾å¼ä¸å®é常åä½Â `? super Type`ï¼è¿è¡¨ç¤ºå¯ä»¥æ¥å Type ç±»åæè
æ¯å®çä»»ä½ç¶ç±»åç对象ã
ä¸çéé
符æå¸¸ç¨äºéè¦åå
¥æä¿®æ¹éåçåºåï¼å 为å®ä»¬æä¾äºå
³äºéåä¸å¯ä»¥æå
¥åªäºç±»å对象çæç¨ä¿¡æ¯ãè¿æå©äºä¿æç±»åå®å
¨ï¼é¿å
å¨éå䏿å
¥ä¸æ£ç¡®çç±»åã
使ç¨ä¸çéé
符çååé常éµå¾ªï¼âProducer Extends, Consumer Superâï¼ç®ç§°PECSï¼ãå®ç± Joshua Bloch æåºï¼æææ¯å¦æä½ è¦ä»ä¸ä¸ªæ°æ®ç»æè·åæ°æ®ï¼å¯ä»¥ç¨Â `extends`ï¼ç产è
ï¼ï¼å¦æä½ è¦ææ°æ®æ¾å
¥ä¸ä¸ªæ°æ®ç»æï¼å°±å¯ä»¥ç¨Â `super`ï¼æ¶è´¹è
ï¼ãè¿ä¸ªå忝æ³å使ç¨ä¸çä¸ä¸ªéè¦æå¯¼ååï¼å¸®å©ä½ åçå°ä½¿ç¨æ³å以åä¿æç±»åå®å
¨ã
å¨å®è·µä¸ï¼ä½¿ç¨ä¸çéé
符å¯ä»¥æé«APIççµæ´»æ§ãä¾å¦ï¼å¨Javaç `Collections` 类ä¸å°±åå¨è¿æ ·çæ¹æ³ï¼
```java
public static void copy(List super T> dest, List extends T> src) {
// ...
}
```
è¿ä¸ªÂ `copy`Â æ¹æ³æå³çä½ å¯ä»¥å°æºå表(src)ä¸çå
ç´ å¤å¶å°ç®æ å表(dest)ä¸ï¼å¹¶ä¸è¿ä¸¤ä¸ªå表å¯ä»¥æä¸åçç±»ååæ°ï¼åªéè¦æ»¡è¶³ç®æ å表çç±»ååæ°æ¯æ¥æºå表çç±»ååæ°çç¶ç±»å³å¯ãè¿æ ·è®¾è®¡å¯ä»¥è®©ä½ å¨ä¸çºç²ç±»åå®å
¨çåæä¸ï¼å¤å¶å¯¹è±¡å°æ´å éç¨ç±»åçå表ä¸å»ã
### 示ä¾
```java
public class GenericsTester {
public static void main(String[] args) {
List animals = new ArrayList<>();
List cats = new ArrayList<>();
List redCats = new ArrayList<>();
List dogs = new ArrayList<>();
addCat(animals);
addCat(cats);
// compile time error
// can not add list of subclass RedCat of Cat class
// addCat(redCats);
// compile time error
// can not add list of subclass Dog of Superclass Animal of Cat class
// addCat.addMethod(dogList);
}
public static void addCat(List super Cat> catList) {
catList.add(new RedCat());
System.out.println("Cat added");
}
}
```
## inï¼éåï¼ãoutï¼ååï¼
为äºç¡®å®åªç§ç±»åçéé
符æéå该æ¡ä»¶ï¼æä»¬å°ä¼ éç»æ¹æ³çåæ°ç±»åå类为è¾å
¥ï¼inï¼åè¾åºï¼outï¼åæ°ã
`in` 表æä¸ä¸ªç±»ååæ°æ¯éåçï¼æå³çè¿ä¸ªæ³åç±»å¨è¿ä¸ªç±»å忰䏿¯ä¸ä¸ªæ¶è´¹è
ãå¯ä»¥å°å
¶ç解为 âåªè¾å
¥ï¼ä¸è¾åºâ çç±»ååæ°ãå¯ä»¥å®å
¨å°ä¼ éç±»å `T` çå¼ç»è¿ä¸ªå¯¹è±¡ï¼ä½ä¸è½å®å
¨å°è¯»åè¿ä¸ªç±»åçå¼ãå¨ Java ä¸ä¸çéé
ç¬¦å¯¹åº `in`ã
```java
public void processElements(List extends Number> list) {
for (Number num : list) {
// å¯ä» list ä¸è¯»å Number æå
¶åç±»åçå
ç´
}
// ä¸å¯ä»¥å°æ°çå
ç´ æ·»å å° list ä¸
}
```
`out`表æä¸ä¸ªç±»ååæ°æ¯ååçï¼æå³çè¿ä¸ªæ³åç±»å¨è¿ä¸ªç±»å忰䏿¯ä¸ä¸ªç产è
ãå¯ä»¥å°å
¶ç®åç解为 âåªè¾åºï¼ä¸è¾å
¥â çç±»ååæ°ãå¯ä»¥å®å
¨å°è¯»ååºç±»å`T`çå¼ï¼ä½ä¸è½åå
¥ç¹å®ç`T`对象ãå¨ Java ä¸ä¸çéé
ç¬¦å¯¹åº `out`ã
```java
public void addNumbers(List super Integer> list) {
list.add(1); // å¯ä»¥å° Integer æ·»å å° list ä¸
// ä¸è½ä¿è¯ä» list ä¸å®å
¨å°è¯»åç¹å®ç±»åçå
ç´
}
```
### 示ä¾
```java
public class GenericsTester {
public static void main(String[] args) {
List animals = new ArrayList<>();
List cats = new ArrayList<>();
List redCats = new ArrayList<>();
addCat(animals);
addCat(cats);
printCat(cats);
printCat(redCats);
}
public static void addCat(List super Cat> catList) {
catList.add(new RedCat()); // / å¯å catList 䏿·»å Cat æå
¶è¶
ç±»åç
// 读åçå
ç´ åªè½åæ¾å¨ Object ç±»åçåéä¸ï¼
// ä¸è½åæ¾å¨ Cat ç±»åçåéä¸ï¼éè¦å¼ºå¶ç±»å转æ¢
for (Object cat : catList) {
System.out.println(cat);
}
}
public static void printCat(List extends Cat> catList) {
for (Cat cat : catList) {
// / å¯ä» catList ä¸è¯»å Cat æå
¶åç±»åç
System.out.println(cat);
}
// ç¼è¯é误ï¼ä¸è½æ·»å å
ç´
// catList.add(new Cat());
}
}
class Animal {}
class Cat extends Animal {}
class RedCat extends Cat {}
```
## ç±»åæ¦é¤
Javaæ³åç±»åæ¦é¤ï¼Type Erasureï¼æ¯ Java ç¼è¯å¨åºç¨çä¸ç§è¿ç¨ï¼å®å
许å¨ç¼åæ³åä»£ç æ¶ä½¿ç¨ç±»ååæ°ï¼èå¨è¿è¡æ¶åç§»é¤è¿äºç±»ååæ°ä¿¡æ¯ãè¿æ ·åçç®çæ¯ä¸ºäºç¡®ä¿æ³å代ç è½ä¸ Java æ©æçæ¬ç代ç å
¼å®¹ã
æ³åæ¯å¨ Java 5ä¸å¼å
¥çä¸ä¸ªç¹æ§ï¼å®å
许å¨ç±»ãæ¥å£åæ¹æ³ä¸ä½¿ç¨ç±»ååæ°ï¼ä»èæä¾æ´å¼ºçç±»åæ£æ¥ï¼å¹¶åå°ä»£ç ä¸çç±»å强转ãå½ä½ ä½¿ç¨æ³åæ¶ï¼ä¾å¦å建ä¸ä¸ªæ³åç±»`ArrayList`ï¼ä½ å¯ä»¥æå®ä¸ä¸ªå
·ä½çç±»åæ¥ä»£æ¿`T`ãæ¯å¦ï¼ä½¿ç¨`ArrayList`å°`T`æå®ä¸º`String`ã
ç±»åæ¦é¤åçå¨ç¼è¯æ¶ï¼ç¼è¯å¨ä½¿ç¨æ³åæ¥è¿è¡ç±»åæ£æ¥ï¼ä½éåä¼ç§»é¤ææçç±»ååæ°å¹¶æ¿æ¢ä¸ºå®ä»¬çéå®ç±»åï¼bounded typesï¼æè
Object ç±»åãè¿æ ·ä¸æ¥ï¼å¨åèç 级å«ï¼æ³åç±»åæ¹æ³å°±åæäºæ®éçç±»åæ¹æ³ï¼å¹¶ä¸ä¸å
å«ä»»ä½æ³åä¿¡æ¯ã
ä¾å¦ï¼
```java
List list = new ArrayList();
```
å¨ç¼è¯ä¹åä¼åæï¼
```java
List list = new ArrayList();
```
å¨è¿ä¸ªä¾åä¸ï¼ç¼è¯åçä»£ç æ`List`åæäº`List`ï¼`ArrayList`åæäº`ArrayList`ãè¿è¡¨ç¤ºå¨è¿è¡æ¶ï¼ä½ ä¸è½ç¥éè¿ä¸ªliståæ¬è¢«æå®çæ¯`String`ç±»åï¼å 为è¿é¨åä¿¡æ¯å·²ç»è¢«æ¦é¤äºãè¿ä¹æ¯ä¸ºä»ä¹ä½ ä¸è½ç´æ¥æ¥è¯¢æ³ååæ°çç±»åä¿¡æ¯ï¼ä¾å¦ï¼ä¸è½ç¨`if (list instanceof ArrayList)`ï¼ã
ç±»åæ¦é¤å¯è½å¼èµ·æäºé®é¢ï¼åæ¯ç±»å转æ¢å¼å¸¸ï¼ClassCastExceptionï¼ï¼å 为æ³ååªå¨ç¼è¯æé´æä¾ç±»åå®å
¨æ§ï¼èå¨è¿è¡æ¶ï¼è¿äºå®å
¨æ§æ£æ¥ä¸å¤åå¨ã为äºåºå¯¹è¿ä¸ªé®é¢ï¼ç¼è¯å¨ä¼å¨å¿
è¦æ¶æå
¥ç±»å转æ¢ä»£ç ï¼ä»¥ç¡®ä¿è¿è¡æ¶çå®å
¨æ§ã
æ»çæ¥è¯´ï¼ç±»åæ¦é¤æ¯ Java ä¸å®ç°æ³åçä¸ç§æä¸åæ³ï¼å®ä¿è¯äºæ³å代ç çå
¼å®¹æ§å䏿§Java 代ç çéæï¼è½ç¶çºç²äºç±»åä¿¡æ¯ã
### ç±»åæ¦é¤è§å
ç±»åæ¦é¤è§åå³å®äºæ³åå¨ç¼è¯è¿ç¨ä¸å¦ä½è¢«è½¬æ¢ä¸ºæ®éçç±»åæ¹æ³è°ç¨ãå
¶ä¸»è¦è§åå¦ä¸ï¼
**æ³åç±»ååæ°æ¦é¤**ï¼ å¦æç±»ååæ°æªæå®ä¸çï¼å¦Â `T`ï¼ï¼åæ¿æ¢ä¸ºÂ `Object`ã å¦æç±»ååæ°æå®äºä¸çï¼å¦Â `T extends Comparable`ï¼ï¼åæ¿æ¢ä¸º `Comparable` ä½ä¸ºä¸çã
**æ³åæ¹æ³åç±»ä¸çç±»ååæ°**ï¼ æ³åæ¹æ³çç±»å忰卿¹æ³è¢«è°ç¨æ¶åæ ·è¿è¡æ¦é¤ï¼ä½¿ç¨ç¸åçè§åï¼æ¿æ¢ä¸ºÂ `Object` ææå®çä¸çï¼ã
**æ¡¥æ¥æ¹æ³ï¼Bridge Methodsï¼**ï¼ å ä¸ºç±»åæ¦é¤å¯è½ä¼å¯¼è´æ¹æ³ç¾åå²çªæä¸æç¡®ï¼Java ç¼è¯å¨å¯è½ä¼çæä¸ä¸ªæå¤ä¸ªæ¡¥æ¥æ¹æ³æ¥ä¿è¯å¤ææ§ãæ¡¥æ¥æ¹æ³æ¯ç¼è¯å¨èªå¨åå»ºçæ¹æ³ï¼å®ä¼è°ç¨åå§æ¹æ³ï¼ä½æ¯å
¶åæ°åè¿åç±»å使ç¨äºæ¦é¤åçç±»åã
**ç±»ååæ°çè¿è¡æ¶æ£æ¥**ï¼ ç±äºç±»åä¿¡æ¯å¨è¿è¡æ¶ä¸å¯ç¨ï¼å æ¤æä»¬æ æ³å¯¹æ³åç±»ååæ°è¿è¡Â `instanceof`Â æ£æ¥ï¼ä¾å¦Â `object instanceof T` æ¯éæ³çï¼ã
**æ³åæ°ç»å建æ¯ä¸åæ³ç**ï¼ å ä¸ºç±»åæ¦é¤ï¼Java ä¸å
è®¸ç´æ¥å建æ³åç±»åçæ°ç»ï¼ä¾å¦Â `new T[]`ï¼ï¼è¿æ¯å 为å¨è¿è¡æ¶æ æ³ç¡®å®å
·ä½çç±»åæ¥ç¡®ä¿ç±»åå®å
¨ã
ç±»åæ¦é¤ç¡®ä¿äºæ³åç±»åå¨è¿è¡æ¶åæ®éç±»ä¸æ ·è¢«å¤çï¼è¿æ ·åç好夿¯ä½¿å¾æ³åè½ä¸ä¹åçæ¬çJava代ç å
¼å®¹ï¼ä½ç¼ºç¹æ¯æäºæ³åæä½å¨è¿è¡æ¶åå¾ä¸å®å
¨æä¸å¯è½æ§è¡ã
### æçç±»åæ¦é¤ç¤ºä¾
å¦æä½¿ç¨æçç±»ååæ°ï¼Java ç¼è¯å¨ä¼å°æ³åç±»åä¸çç±»ååæ°æ¿æ¢ä¸ºå
¶ç»å®çç±»ååæ°ã
```java
// æºä»£ç
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box();
Box doubleBox = new Box();
integerBox.add(new Integer(10));
doubleBox.add(new Double(10.0));
System.out.printf("Integer Value :%d\n", integerBox.get());
System.out.printf("Double Value :%s\n", doubleBox.get());
}
}
class Box {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
```
å¨è¿ç§æ
åµä¸ï¼Java ç¼è¯å¨å°ç¨ Number ç±»æ¿æ¢ Tï¼å¹¶ä¸å¨ç±»åæ¦é¤åï¼ç¼è¯å¨å°ä¸ºä»¥ä¸ä»£ç çæåèç ã
```java
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box();
Box doubleBox = new Box();
integerBox.add(new Integer(10));
doubleBox.add(new Double(10.0));
System.out.printf("Integer Value :%d\n", integerBox.get());
System.out.printf("Double Value :%s\n", doubleBox.get());
}
}
class Box {
private Number t;
public void add(Number t) {
this.t = t;
}
public Number get() {
return t;
}
}
```
### æ çç±»åæ¦é¤ç¤ºä¾
å¦æä½¿ç¨æ çç±»ååæ°ï¼Java ç¼è¯å¨ä¼å°æ³åç±»åä¸çç±»ååæ°æ¿æ¢ä¸º Objectã
```java
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box();
Box stringBox = new Box();
integerBox.add(new Integer(10));
stringBox.add(new String("Hello World"));
System.out.printf("Integer Value :%d\n", integerBox.get());
System.out.printf("String Value :%s\n", stringBox.get());
}
}
class Box {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
```
å¨è¿ç§æ
åµä¸ï¼Java ç¼è¯å¨å°ç¨ Object ç±»æ¿æ¢ Tï¼å¹¶ä¸å¨ç±»åæ¦é¤åï¼ç¼è¯å¨å°ä¸ºä»¥ä¸ä»£ç çæåèç ã
```java
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box();
Box stringBox = new Box();
integerBox.add(new Integer(10));
stringBox.add(new String("Hello World"));
System.out.printf("Integer Value :%d\n", integerBox.get());
System.out.printf("String Value :%s\n", stringBox.get());
}
}
class Box {
private Object t;
public void add(Object t) {
this.t = t;
}
public Object get() {
return t;
}
}
```
### æ³åæ¹æ³ç±»åæ¦é¤ç¤ºä¾
å¦æä½¿ç¨æ çç±»ååæ°ï¼Java ç¼è¯å¨å°æ³åç±»åä¸çç±»ååæ°æ¿æ¢ä¸º Objectï¼å¦æä½¿ç¨æçç±»ååæ°ä½ä¸ºæ¹æ³åæ°ï¼å Java ç¼è¯å¨å°æ¿æ¢ç±»ååæ°ã
```java
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box();
Box stringBox = new Box();
integerBox.add(10);
stringBox.add(new String("Hello World"));
printBoundBox(integerBox);
printUnboundBox(stringBox);
}
private static void printBoundBox(T box) {
System.out.println("Integer Value :" + box.get());
}
private static void printUnboundBox(T box) {
System.out.println("String Value :" + ((Box)box).get());
}
}
class Box {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
```
å¨è¿ç§æ
åµä¸ï¼Java ç¼è¯å¨å°ç¨ Object ç±»æ¿æ¢ Tï¼å¹¶ä¸å¨ç±»åæ¦é¤åï¼ç¼è¯å¨å°ä¸ºä»¥ä¸ä»£ç çæåèç ã
```java
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box();
Box stringBox = new Box();
integerBox.add(10);
stringBox.add(new String("Hello World"));
printBoundBox(integerBox);
printUnboundBox(stringBox);
}
//Bounded Types Erasure
private static void printBoundBox(Box box) {
System.out.println("Integer Value :" + box.get());
}
//Unbounded Types Erasure
private static void printUnboundBox(Object box) {
System.out.println("String Value :" + ((Box)box).get());
}
}
class Box {
private Object t;
public void add(Object t) {
this.t = t;
}
public Object get() {
return t;
}
}
```
## æ³åéå¶
### 䏿¯æåºæ¬ç±»å
ä½¿ç¨æ³åæ¶ï¼åºæ¬ç±»åä¸è½ä½ä¸ºç±»ååæ°ä¼ éãå¨ä¸é¢ç»åºç示ä¾ä¸ï¼å¦ææä»¬å° int ç±»åä¼ éç» Box ç±»ï¼é£ä¹ç¼è¯å¨ä¼æ¥éã为äºè§£å³è¿ç§æ
åµï¼æä»¬éè¦ä¼ é Integer 对象è䏿¯ int åºæ¬ç±»åã
```java
public class GenericsTester {
public static void main(String[] args) {
Box integerBox = new Box();
//Syntax error
//Box stringBox = new Box();
integerBox.add(10);
printBox(integerBox);
}
private static void printBox(Box box) {
System.out.println("Value: " + box.get());
}
}
class Box {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
```
### ä¸è½å®ä¾åæ³åç±»ååæ°
ç±»ååæ°ä¸è½å¨æ¹æ³å
å®ä¾åå
¶å¯¹è±¡ã
```java
public static void add(Box box) {
// compiler error
// Cannot instantiate the type T
// T item = new T();
// box.add(item);
}
```
è¦å®ç°æ¤ç±»åè½ï¼è¯·ä½¿ç¨åå°ã
```java
public static void add(Box box, Class clazz)
throws InstantiationException, IllegalAccessException{
T item = clazz.newInstance(); // OK
box.add(item);
System.out.println("Item added.");
}
```
### ä¸è½ä½¿ç¨éæåé
ä½¿ç¨æ³åæ¶ï¼ç±»ååæ°ä¸å
许为éæåéï¼`static`ï¼ãç±äºéæåéå¨å¯¹è±¡ä¹é´å
±äº«ï¼å æ¤ç¼è¯å¨æ æ³ç¡®å®è¦ä½¿ç¨çç±»åã
```java
class Box {
// compiler error
private static T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
```
### ä¸è½è½¬æ¢ç±»å
æ³åä¸ä¸ªç±»çå®ä¾ä¸è½ç´æ¥è½¬æ¢ä¸ºå¦ä¸ä¸ªæ³åç±»ååæ°ä¸åçå®ä¾ï¼å³ä½¿å®ä»¬çåå§ç±»åæ¯ç¸åçãæ¯å¦Â `List` ä¸è½è½¬æ¢ä¸ºÂ `List`ã
```java
Box integerBox = new Box();
Box numberBox = new Box();
// Compiler Error: Cannot cast from Box to Box
integerBox = (Box)numberBox;
```
为äºå®ç°ä¸é¢åè½è½¬æ¢åè½ï¼å¯ä»¥ä½¿ç¨æ çéé
符ã
```java
private static void add(Box> box) {
Box integerBox = (Box)box;
}
```
### ä¸è½ä½¿ç¨ instanceof è¿ç®ç¬¦
å 为ç¼è¯å¨ä½¿ç¨ç±»åæ¦é¤ï¼è¿è¡æ¶ä¸ä¼è·è¸ªç±»ååæ°ï¼æä»¥å¨`Box`å`Box ` ä¹é´çè¿è¡æ¶å·®å¼æ æ³ä½¿ç¨ `instanceOf` è¿ç®ç¬¦è¿è¡éªè¯ãæä»¥ç±»ä¼¼ä¸é¢ç代ç ç¨æ³æ¯é误çï¼
```java
Box integerBox = new Box();
// ç¼è¯é误ï¼
// ä¸å
è®¸å¯¹åæ°åç±»åè¿è¡ instanceof æ£æ¥
// åæ°åç±»å Box ç instanceof æ£æ¥æ¯ä¸å
许ç
// ä½¿ç¨ Box> å½¢å¼ï¼å 为æ³åç±»åä¿¡æ¯å°å¨è¿è¡æ¶è¢«æ¦é¤
if(integerBox instanceof Box) { }
```
### 䏿¯ææ°ç»
ä¸å
许使ç¨åæ°åç±»åçæ°ç»ãå¦ä¸ä»£ç æ¯é误çï¼
```java
// Cannot create a generic array of Box
Box[] arrayOfLists = new Box[2];
```
å 为ç¼è¯å¨ä½¿ç¨ç±»åæ¦é¤ï¼ç±»ååæ°è¢«æ¿æ¢ä¸º`Object`ï¼ç¨æ·å¯ä»¥åæ°ç»æ·»å ä»»ä½ç±»åç对象ãä½å¨è¿è¡æ¶ï¼ä»£ç å°æ æ³æåº`ArrayStoreException`ã
```java
// compiler error, but if it is allowed
Object[] stringBoxes = new Box[];
// OK
stringBoxes[0] = new Box();
// An ArrayStoreException should be thrown,
// but the runtime can't detect it.
stringBoxes[1] = new Box();
```
### ä¸è½ä½¿ç¨å¼å¸¸
æ³åä¸å
è®¸ç´æ¥æé´æ¥ç»§æ¿`Throwable`ç±»ã
```java
// The generic class Box may not subclass java.lang.Throwable
class Box extends Exception {}
// The generic class Box may not subclass java.lang.Throwable
class Box1 extends Throwable {}
```
卿¹æ³ä¸ï¼ä¸å
许æè·ç±»ååæ°çå®ä¾ï¼å¦ä¸ä»£ç
```java
public static void execute(List jobs) {
try {
for (J job : jobs) {}
// compile-time error
// Cannot use the type parameter T in a catch block
} catch (T e) {
// ...
}
}
```
ç±»ååæ°è¿è¡ä½¿ç¨ Throwable 以åå
¶åç±»ã
```java
class Box {
private int t;
public void add(int t) throws T {
this.t = t;
}
public int get() {
return t;
}
}
```
### éè½½éå¶
å¦æä¸¤ä¸ªæ¹æ³çç¾å卿¦é¤æ³ååç¸åï¼åä¸è½éè½½è¿ä¸¤ä¸ªæ¹æ³ã
```java
class Box {
// Compiler error
// Erasure of method print(List)
// is the same as another method in type Box
public void print(List stringList) { }
public void print(List integerList) { }
}
```
æç»å¨ç¼è¯åçåèç ä¸è¿ä¸¤ä¸ªæ¹æ³é½ä¼åæå¦ä¸ç¾å
```java
class Box {
public void print(List list) { }
}
```