泛型也能夠應用於接口,例如生成器,一種專門負責建立對象的類。這實際上是工廠方法設計模式的一種應用。不過使用生成器建立對象時,不須要參數。而工廠方法通常是須要參數的。java
package tik4.generic; public interface Generator<T> { T next(); }
一個Fibonacci數列實現設計模式
package tik4.generic; public class Fibonacci implements Generator<Integer> { private int count; // 參數類型用Integer,使用int將不能編譯 // public int next() { // return 0; // } public Integer next() { return fib(count++); } private int fib(int n) { if (n < 2) return 1; return fib(n - 2) + fib(n - 1); } public static void main(String[] args) { Fibonacci gen = new Fibonacci(); for (int i = 0; i <= 17; i++) System.out.print(gen.next() + " "); } /* * Output: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 */ }
能夠在類中包含參數化方法,而這個方法所在的類能夠是泛型類,也能夠不是泛型類。是否擁有泛型方法,和所在的類是否泛型沒有關係。泛型方法使得該方法可以獨立於類而產生變化。如下是一個基本原則:若是泛型方法能夠取代整個類的泛型化,就應該只使用泛型方法。另外,對於一個static方法而言,沒法訪問泛型app
類的參數類型,因此static方法須要使用泛型能力,就必須成爲泛型方法ide
package tik4.generic; public class GenericMothod { public <T,M,N> void getTType(T t,M m,N n){ /* * 傳入int,long ,double等基本類型時,自動打包機制 * 會將基本類型包裝成相應的對象 */ System.out.println(t.getClass().getName()); System.out.println(m.getClass().getName()); System.out.println(n.getClass().getName()); } public static void main(String[] args) { //泛型類在建立對象時必須指定參數類型,而泛型方法則不須要在建立對象時指定參數類型T GenericMothod gm = new GenericMothod(); gm.getTType("", 1, 1.0); gm.getTType(1.0F, 'c', gm); }/* *Output: java.lang.String java.lang.Integer java.lang.Double java.lang.Float java.lang.Character tik4.generic.GenericMothod */ }
問題:很煩這種寫法是否是,老子在聲明變量的的時候已經指明瞭參數類型,爲毛還要在初始化對象時再指定?工具
Map<Integer, List<? extends Set<String>>> map = new HashMap<Integer, List<? extends Set<String>>>();
解決:搞一個工具類this
package tik4.generic; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; public class New { public static <K, V> Map<K, V> hashMap() { return new HashMap<K, V>(); } public static void main(String[] args) { Map<Integer, List<? extends Set<String>>> map = New.hashMap(); } }
注意:spa
類型推斷只對賦值操做有效,其餘時候不起做用。若是你使用泛型方法調用的結果(例如:New.hashMap())做爲參數,傳遞給其餘方法,此時編譯器不會執行類型推斷。編譯器認爲,調用泛型方法以後,其返回值被賦給一個Object類型的變量。上代碼:設計
package tik4.generic; import java.util.List; import java.util.Map; import java.util.Set; public class LimitsOfInference { static void f(Map<Integer, List<? extends Set<String>>> map){}; public static void main(String[] args) { /* * the mothed f(Map<Integer, List<? extends Set<String>>> * is not applicable for arguments (Map<Object,Object>) * 不能編譯 */ // f(New.hashMap()); } }
在泛型方法中,能夠顯示的指定參數類型。在 點操做符 和 方法名之間插入尖括號,而後將類型置於括號內。若是是在定義該方法的類的內部,則在點操做符以前使用this關鍵字若是使用static方法,必須在點操做符以前加上類名。這種語法,能夠解決LimitsOfInference.java中的問題。code
package tik4.generic; import java.util.List; import java.util.Map; import java.util.Set; public class ExplicitTypeSpecification { static void f(Map<Integer, String> map){}; public static void main(String[] args) { //java 5和java6 中均不能編譯。 f(New.<Map<Integer, String>>hashMap()); } }