在 那些角括號是什麼東西 看過泛型(Generic)的基礎,接下來再深入探討一下。考慮你要製作一個節點物件,節點可內含的物件可以指定其型態(就如同List、Set等內含元素可指定型態),你可以使用泛型語法如下進行定義:
class Node<T> { Node<T> next; private T value; T getValue() { return value; } void setValue(T value) { this.value = value; } } 你使用<>括住一個代表型態的名稱,之後就可以先使用該名稱來宣告變數,名稱所代表的型態是未定的,你要在建立物件時指定型態,例如指定型態為String:
public class Main { public static void main(String[] args) { Node<String> first = new Node<String>(); first.setValue("Justin"); first.next = new Node<String>(); first.next.setValue("momor"); } } 在上例中,將Node定義中的T指定為String,所以getValue()傳回String,而setValue()方法可以接受String,value的型態也是String。你也可以指定別的型態:
public class Main { public static void main(String[] args) { Node<Integer> first = new Node<Integer>(); first.setValue(100); first.next = new Node<Integer>(); first.next.setValue(200); } } 在上例中,將Node定義中的T指定為Integer,所以getValue()傳回Integer,而setValue()方法可以接受Integer,value的型態也是Integer。泛型也可以用在方法定義上,例如在 多維矩陣轉一維矩陣 的例子中,若想讓方法更一般化,則可以如下撰寫:
class ArrayUtil { @SuppressWarnings(value={"unchecked"}) public static <T> T[] toOneByColumn(T[][] array) { T[] arr = (T[]) Array.newInstance( array[0].getClass().getComponentType(), array.length * array[0].length); for(int row = 0; row < array.length; row++) { for(int column = 0; column < array[0].length; column++) { arr[row + column * array.length] = array[row][column]; } } return arr; } }
public class Main { public static void main(String[] args) { Integer[][] arr1 = { {1, 2, 3}, {4, 5, 6} }; for(Integer i : ArrayUtil.<Integer>toOneByColumn(arr1)) { System.out.println(i); } String[][] arr2 = { {"one", "two", "three"}, {"four", "five", "six"} }; for(String s : ArrayUtil.<String>toOneByColumn(arr2)) { System.out.println(s); } } } 泛型也可以用來宣告不定長度引數,例如:
public class Main { public static void main(String[] args) { Main.<Integer>show(1, 2); Main.<String>show("one", "two", "three"); } static <T> void show(T... values) { for(T v : values) { System.out.println(v); } } } 在定義介面時,也可以使用泛型,例如在 神奇的 foreach 看過的 java.util.Iterator[E]:
package java.util;
public interface Iterator<E> { boolean hasNext(); E next(); void remove(); } Iterator[E]可以在使用時宣告A的型態,一個在 神奇的 foreach 看過的例子如下:
import java.util.*; public class Some implements Iterable<String>{ private String[] strs; private int index; public Some(int length) { strs = new String[length]; } public void add(String element) { strs[index++] = element; } public Iterator<String> iterator() { return new Iterator<String>() { private int index; public boolean hasNext() { return index < strs.length; } public String next() { return strs[index++]; } public void remove() { strs[index] = null; } }; } }
|