標籤:simple r++ end cap static lang 調用 generator bsp
1、簡單泛型
使用Object:因為Object類是類階層的根,Java中所有的類從根本上都繼承自這個類。所以所有的類都能轉型為Object類。
import java.util.*;public class Ex7 { static void f(Object a) { System.out.println(a); } public static void main(String[] args) { f("233"); f(233); f(2.33); List<Object> list = new ArrayList<Object>(); list.add("233"); list.add(233); list.add(2.33); for(Object a : list) { System.out.println(a); } }}
這裡的f()函數可以處理三種類型的對象,list也可以存放三種類型的對象,但是其實他們都是處理或者儲存的先轉型為Object類型的對象。
輸出:
2332332.332332332.33
通常而言,我們只會使用容器來儲存一直類型的對象,泛型的主要目的之一就在於此,指定容器要持有什麼類型的對象,然後由編譯器來保證類型的正確性。
要達到這個目的,需要使用型別參數,用角括弧括住,放在類名後面,然後在使用這個類的時候用實際的類型替換此型別參數。
public class Ex7<T> { void f(T a) { System.out.println(a); } public static void main(String[] args) { Ex7<String> exStr = new Ex7<String>(); exStr.f("233"); Ex7<Integer> exInt = new Ex7<Integer>(); exInt.f(2); Ex7<Double> exDou = new Ex7<Double>(); exDou.f(2.5); }}
當你建立Ex7對象時,必須指明想要持有的是什麼類型的對象,將其置於角括弧中。然後你就只能在這個Ex7對象中存入該類型或是其子類。
輸出:
23322.5
2、一個元組類庫
有時候我們希望一次返回就能返回多個對象,但是return語句只允許返回單個對象,所以解決方案就是建立一個對象,用它來持有想要返回的多個對象。
這樣的概念稱為元組,它是將一組對象直接打包儲存於其中的一個單一對象,這個容器物件允許對象讀取其中的元素,但是不允許向其中存放新的對象。因為是元嘛,所以只能用不能修改,要修改就得弄一個新的,不過這個不重要==
class TwoTuple<A,B>{ public final A first; public final B second; public TwoTuple(A a, B b) { first = a; second = b; } public String toString() { return "(" + first + "," + second + ")"; }}class FiveTuple<A,B,C,D,E> extends TwoTuple { public final C third; public final D fourth; public final E fifth; public FiveTuple(A a, B b,C c,D d,E e) { super(a, b); third = c; fourth = d; fifth = e; } public String toString() { return "(" + first + "," + second + "," + third + "," + fourth + "," + fifth + "," + ")"; }}
- 元組是可以具有任意長度的,這裡建立了兩個長度分別為2和5的元組,
- 元組中的對像可以是任意不同的類型的,不過最好是為每一個對象指明其類型。
- 還有之前說的可以讀取,但是不允許存放新的元素和修改,final就解決這個問題了
- toString只是用來顯示列表中的值的
class new1{}class new2{}public class Ex8 { static TwoTuple<new1,Integer> f(){ return new TwoTuple<new1,Integer>(new new1(),2); } static TwoTuple<new1,Double> f1(){ return new TwoTuple<new1,Double>(new new1(),2.5); } static FiveTuple<new1,new2,Integer,Double,Double> g(){ return new FiveTuple<new1,new2,Integer,Double,Double> (new new1(),new new2(), 2, 2.3, 2.3); } static FiveTuple<new1,new2,Integer,Integer,String> g1(){ return new FiveTuple<new1,new2,Integer,Integer,String> (new new1(),new new2(), 2, 2, "2"); } public static void main(String[] args) { TwoTuple<new1,Integer> test = f(); System.out.println(test); System.out.println(f1()); System.out.println(g()); System.out.println(g1()); }}
輸出:
([email protected],2)([email protected],2.5)([email protected],[email protected]4e25154f,2,2.3,2.3,)([email protected],[email protected],2,2,2,)
3、泛型介面
interface Generator<T>{ T next();}class Coffee{ private static long counter = 0; private final long id = counter++; public String toString() { return getClass().getSimpleName() + " " + id; }}class Mocha extends Coffee{}class Latte extends Coffee{}class Cappuccino extends Coffee{}public class Ex9 implements Generator<Coffee>{ private Class[] type = {Mocha.class, Latte.class, Cappuccino.class}; private Random rand = new Random(47); public Coffee next() { try { return (Coffee) type[rand.nextInt(type.length)].newInstance(); } catch(Exception e) { throw new RuntimeException(e); } } public static void main(String[] args) { Ex9 ex = new Ex9(); for(int i = 0; i < 5; i++) System.out.println(ex.next()); }}
Generator<T>介面是一個用來專門負責產生對象的類,其中的next用於產生新的對象,然後實現這個介面的時候就需要指定這個T
輸出:
Cappuccino 0Cappuccino 1Latte 2Cappuccino 3Latte 4
然後是一個產生斐波那契數列的類的例子:
interface Generator<T>{ T next();}public class Ex9 implements Generator<Integer>{ private int counter = 0; public Integer next() { return fib(counter++); } private int fib(int n){ if(n < 2) return 1; return fib(n - 2) + fib(n - 1); } public static void main(String[] args) { Ex9 ex = new Ex9(); for(int i = 0; i < 18; i++) System.out.print(ex.next() + " "); }}
輸出:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
4、泛型方法
要定義泛型方法,只需將泛型參數列表置於傳回值之前
public class Exp10 { public <T>void f(T x){ System.out.println(x.getClass().getName()); } public static void main(String[] args) { Exp10 ex = new Exp10(); ex.f("x"); ex.f(2); ex.f(2.3); ex.f(2l); ex.f(4.55f); }}
輸出:
java.lang.Stringjava.lang.Integerjava.lang.Doublejava.lang.Longjava.lang.Float
在建立泛型類的時,必須在建立對象的時候指定型別參數的類型,而使用泛型方法的時候,通常不需要指明參數類型,編譯器會為我們找出具體的類型,這被稱為型別參數推斷,我們像調用普通方法那樣調用f(),就像f()被無限次重載了一樣。
java——泛型