Java泛型tutorial
Java泛型 is Java 5引入 一个 important features, 它允许 in 定义class, interface and method时usingclass型parameter, 使code更加flexible, class型security and reusable . 本tutorial将详细介绍Java泛型 core concepts and 实践techniques, helping您Master泛型programming 精髓.
1. 泛型overview
1.1 what is 泛型?
泛型 is aparameter化class型 mechanism, 它允许 in 定义class, interface and method时usingclass型parameter, 而不 is 具体 class型. class型parameter in using时被practicalclass型replace, from 而implementationcode 重用 and class型security.
1.2 泛型 优点
- class型security: 泛型可以 in 编译时检测class型error, 而不 is in run时.
- code重用: 泛型允许writing适用于 many 种class型 code, improvingcode reusability.
- 消除强制class型转换: using泛型可以避免不必要 class型转换, 使code更加简洁.
- 更 good code readable 性: 泛型可以使code 意graph更加明确, improvingcode readable 性.
2. 泛型class and interface
2.1 泛型class 定义
// 泛型class 定义 public class Box{ private T content; public void setContent(T content) { this.content = content; } public T getContent() { return content; } } // using泛型class public class BoxExample { public static void main(String[] args) { // creationstoreIntegerclass型 Box Box integerBox = new Box<>(); integerBox.setContent(10); Integer integerValue = integerBox.getContent(); System.out.println("Integer value: " + integerValue); // creationstoreStringclass型 Box Box stringBox = new Box<>(); stringBox.setContent("Hello, Generics!"); String stringValue = stringBox.getContent(); System.out.println("String value: " + stringValue); } }
2.2 泛型interface 定义
// 泛型interface 定义 public interface List{ void add(T element); T get(int index); int size(); } // implementation泛型interface public class ArrayList implements List { private Object[] elements; private int size; public ArrayList(int capacity) { elements = new Object[capacity]; size = 0; } @Override public void add(T element) { if (size < elements.length) { elements[size] = element; size++; } } @Override @SuppressWarnings("unchecked") public T get(int index) { if (index >= 0 && index < size) { return (T) elements[index]; } throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } @Override public int size() { return size; } } // using泛型interface public class ListExample { public static void main(String[] args) { List list = new ArrayList<>(10); list.add("Java"); list.add("Generics"); list.add("Tutorial"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } }
2.3 many class型parameter
// many class型parameter 泛型class public class Pair{ private K key; private V value; public Pair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } public void setKey(K key) { this.key = key; } public void setValue(V value) { this.value = value; } } // using many class型parameter 泛型class public class PairExample { public static void main(String[] args) { Pair pair1 = new Pair<>("Age", 25); System.out.println("Key: " + pair1.getKey() + ", Value: " + pair1.getValue()); Pair pair2 = new Pair<>(1, "Java"); System.out.println("Key: " + pair2.getKey() + ", Value: " + pair2.getValue()); } }
3. 泛型method
3.1 泛型method 定义
public class GenericMethodExample {
// 泛型method
public static void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
// 带 has return value 泛型method
public static T getFirstElement(T[] array) {
if (array != null && array.length > 0) {
return array[0];
}
return null;
}
public static void main(String[] args) {
// test泛型method
Integer[] intArray = {1, 2, 3, 4, 5};
String[] stringArray = {"Java", "Generics", "Method"};
Double[] doubleArray = {1.1, 2.2, 3.3};
System.out.println("Integer array:");
printArray(intArray);
System.out.println("String array:");
printArray(stringArray);
System.out.println("Double array:");
printArray(doubleArray);
// test带 has return value 泛型method
System.out.println("First element of intArray: " + getFirstElement(intArray));
System.out.println("First element of stringArray: " + getFirstElement(stringArray));
}
}
3.2 class型parameter推断
in Java 7及以 on versionin, using泛型method时可以省略class型parameter, 编译器会根据 on under 文自动推断class型parameter.
public class TypeInferenceExample {
public static T getDefaultValue() {
return null;
}
public static void printValue(T value) {
System.out.println(value);
}
public static void main(String[] args) {
// 显式指定class型parameter
String str1 = TypeInferenceExample.getDefaultValue();
// class型parameter推断
String str2 = getDefaultValue(); // 编译器推断T for String
Integer num = getDefaultValue(); // 编译器推断T for Integer
// method调用in class型parameter推断
printValue("Hello"); // 编译器推断T for String
printValue(42); // 编译器推断T for Integer
printValue(3.14); // 编译器推断T for Double
}
}
4. class型edge界
4.1 on 界通配符
on 界通配符usingextends关键字, 限制class型parameter必须 is 指定class型 or 其子class型.
public class UpperBoundExample {
// on 界通配符
public static double sumOfList(List extends Number> list) {
double sum = 0.0;
for (Number number : list) {
sum += number.doubleValue();
}
return sum;
}
public static void main(String[] args) {
List intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
System.out.println("Sum of intList: " + sumOfList(intList));
List doubleList = new ArrayList<>();
doubleList.add(1.1);
doubleList.add(2.2);
doubleList.add(3.3);
System.out.println("Sum of doubleList: " + sumOfList(doubleList));
}
}
4.2 under 界通配符
under 界通配符usingsuper关键字, 限制class型parameter必须 is 指定class型 or 其父class型.
public class LowerBoundExample {
// under 界通配符
public static void addNumbers(List super Integer> list) {
for (int i = 1; i <= 5; i++) {
list.add(i);
}
}
public static void main(String[] args) {
List intList = new ArrayList<>();
addNumbers(intList);
System.out.println("intList: " + intList);
List numberList = new ArrayList<>();
addNumbers(numberList);
System.out.println("numberList: " + numberList);
List
5. class型擦除
5.1 what is class型擦除?
class型擦除 is Java泛型 implementationmechanism, 它 in 编译时将泛型class型parameterreplace for 其edge界class型 (such as果没 has 指定edge界, 则replace for Object) , from 而生成非泛型 bytecode.
5.2 class型擦除 影响
- run时无法获取泛型class型parameter practicalclass型
- 不能usingbasicclass型serving as泛型class型parameter
- 不能creation泛型class型 array
- 不能 in 静态 on under 文inusing泛型class型parameter
public class TypeErasureExample {
public static void main(String[] args) {
Box intBox = new Box<>();
Box stringBox = new Box<>();
// class型擦除 after , intBox and stringBox class型都 is Box
System.out.println("intBox.getClass(): " + intBox.getClass());
System.out.println("stringBox.getClass(): " + stringBox.getClass());
System.out.println("intBox.getClass() == stringBox.getClass(): " + (intBox.getClass() == stringBox.getClass()));
}
}
class Box {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
6. 泛型 限制
- 不能usingbasicclass型serving asclass型parameter: such asList
is 不允许 , 必须usingList . - 不能creation泛型class型 instance: such asnew T() is 不允许 .
- 不能creation泛型class型 array: such asnew T[10] is 不允许 .
- 不能 in 静态 on under 文inusing泛型class型parameter: 静态variable and method不能usingclass 泛型class型parameter.
- 不能usinginstanceof运算符check泛型class型: such asinstanceof List
is 不允许 .
实践case: 泛型toolclass
creation一个泛型toolclass, providing常用 泛型method, such asarray转collection, collection转array, 最 big 值findetc..
import java.util.ArrayList;
import java.util.List;
public class GenericUtils {
// array转collection
public static List arrayToList(T[] array) {
List list = new ArrayList<>();
if (array != null) {
for (T element : array) {
list.add(element);
}
}
return list;
}
// collection转array
@SuppressWarnings("unchecked")
public static T[] listToArray(List list, T[] array) {
if (list == null) {
return null;
}
return list.toArray(array);
}
// find最 big 值
public static > T findMax(T[] array) {
if (array == null || array.length == 0) {
return null;
}
T max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i].compareTo(max) > 0) {
max = array[i];
}
}
return max;
}
// 交换arrayin 两个元素
public static void swap(T[] array, int i, int j) {
if (array != null && i >= 0 && i < array.length && j >= 0 && j < array.length) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
// test泛型toolclass
public static void main(String[] args) {
// testarray转collection
Integer[] intArray = {1, 2, 3, 4, 5};
List intList = arrayToList(intArray);
System.out.println("Array to List: " + intList);
// testcollection转array
String[] stringArray = listToArray(intList, new Integer[0]);
System.out.println("List to Array: " + java.util.Arrays.toString(stringArray));
// testfind最 big 值
Integer[] numbers = {5, 2, 9, 1, 7};
System.out.println("Max value: " + findMax(numbers));
// test交换元素
swap(numbers, 0, 2);
System.out.println("After swap: " + java.util.Arrays.toString(numbers));
}
}
这个泛型toolclass展示了such as何using泛型creationcommon toolmethod:
- using泛型methodimplementationarray and collection之间 转换
- using on 界通配符implementation最 big 值find
- using泛型methodimplementation元素交换
互动练习
练习1: implementation一个泛型栈
writing一个Java程序, implementation一个泛型栈, support以 under operation:
- push: 将元素压入栈顶
- pop: from 栈顶弹出元素
- peek: 查看栈顶元素但不弹出
- isEmpty: check栈 is 否 for 空
- size: 获取栈 big small
练习2: implementation泛型sortmethod
writing一个Java程序, implementation一个泛型sortmethod, able to for 任意implementation了Comparableinterface class型 arrayforsort.
练习3: implementation泛型cache
writing一个Java程序, implementation一个泛型cache, support以 under operation:
- put: 将键值 for 放入cache
- get: 根据键获取值
- remove: 根据键移除cache项
- clear: 清空cache
- size: 获取cache big small