在 那些角括號是什麼東西 看過泛型(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;
                   }
               };
    }
}
