Java 泛型學習記錄

日常編碼時泛型的體現簡直無處不在,但是對其一直沒有系統的學習過,今天就來學習一下!老樣子,先百度其他大牛已經寫好的博客來看,對於這種經典的知識點,網上肯定已經有很多了。下面這篇就已經寫得很詳細了,可以說超級好理解!

Java泛型詳解:<T>和Class<T>的使用。泛型類,泛型方法的詳細使用實例

原博客已經寫得超級詳細了(雖然大佬也是轉載其他博客哈哈哈),小渣就不重複贅述了。爲了加深理解泛型的概念,先將大佬博客中的實例復現一波:

1. 首先看看怎麼實現一個泛型接口

package com.wjb.generic;
/**
 * 泛型接口實例
 * @author Administrator
 *
 * @param <T>
 */
interface Info<T>{
	public T getVar();
	public void setVar(T var);
}

public class InfoImpl implements Info<String>{
	private String var;
	public InfoImpl(String var) {
		this.setVar(var);
	}

	@Override
	public String getVar() {
		// TODO Auto-generated method stub
		return this.var;
	}

	@Override
	public void setVar(String var) {
		this.var = var;
	}
	
	public static void main(String[] args) {
		InfoImpl info = new InfoImpl("泛型接口");
		System.out.println(info.getVar());
	}
}

在這裏我們將Info<String>中的泛型變量T定義填充爲了String類型。所以在重寫時setVar()和getVar()時,IDE會也我們直接生成String類型的重寫函數。(所以要注意,如果是手動重新的話注意類型要相應改爲String!)

2. 實現泛型類

package com.wjb.generic;
/**
 * 泛型接口實例
 * @author Administrator
 *
 * @param <T>
 */
interface Info<T>{
	public T getVar();
	public void setVar(T var);
}

public class InfoImpl<T> implements Info<T>{ //使用泛型類來繼承泛型接口
	private T var;
	public InfoImpl(T var) {
		this.setVar(var);
	}

	@Override
	public T getVar() {
		// TODO Auto-generated method stub
		return this.var;
	}

	@Override
	public void setVar(T var) {
		this.var = var;
	}
	
	public static void main(String[] args) {
		InfoImpl<String> info = new InfoImpl<String>("泛型類");
		System.out.println(info.getVar());
	}
}

值得注意的是,這樣寫乍看起來更繁瑣了些。但是這樣寫的一大好處就是:使用泛型類來繼承泛型接口的作用就是讓用戶來定義接口所使用的變量類型,而不是像方法一那樣,在類中寫死。

3.泛型方法

“泛型方法”就沒上面那兩個好理解了,所以這裏要大概講解一下。泛型類,是在實例化類的時候指明泛型的具體類型;泛型方法,是在調用方法的時候指明泛型的具體類型。 說明一下,定義泛型方法時,必須在返回值前邊加一個<T>,來聲明這是一個泛型方法。持有一個泛型T,然後纔可以用泛型T作爲方法的返回值(這裏注意體會一下上面代碼中getVar()方法的返回值也是T)。

package com.wjb.generic;
/**
 * 泛型方法
 * @author Administrator
 *
 */
public class StaticFans {
	//定義一個靜態泛型方法
	public static <T> T staticMethod(T a) {
		System.out.println("StaticMethod: "+a.toString());
		return a;
	}
	
	//定義一個常規泛型方法
	public <T> void otherMethod(T a) {
		System.out.println("OtherMethod: "+a.toString());
	}
	
	public static void main(String[] args) {
		StaticFans.staticMethod("靜態泛型方法1");//使用方法1
		StaticFans.<String>staticMethod("靜態泛型方法2");//使用方法2
		
		StaticFans sf = new StaticFans();
		sf.otherMethod("常規泛型方法1");//使用方法1
		sf.<String>otherMethod("常規泛型方法2");//使用方法2
	}
}

泛型方法只要記得在返回值前加個<T>就行了,對於代碼中的兩種使用方法,方法1是隱式的參數傳遞,需要編譯器幫我們識別傳遞的參數類型,儘量不要使用這種隱式的傳遞方式,代碼不利於閱讀和維護。因爲從外觀根本看不出來你調用的是一個泛型函數。方法2與方法1不同的地方在於,在調用方法前加了一個<String>來指定傳給<T>的值,如果加了這個<String>來指定參數的類型的話,那StaticMethod()函數裏所有用到的T類型也就是強制指定了是String類型。這是我們建議使用的方式。

那泛型方法存在的意義是什麼呢: 因爲泛型類要在實例化的時候就指明類型,如果想換一種類型,不得不重新new一次,可能不夠靈活;而泛型方法可以在調用的時候指明類型,更加靈活。因此,當方法的參數類型爲泛型時,就必須將方法定義爲泛型方法。

4. 泛型數組

package com.wjb.generic;
/**
 * 泛型數組
 * @author Administrator
 *
 */
public class Funs {
	public static <T> T[] fun(T...arg) {// 接收可變長參數    
		return arg; //返回可變數組
	}
	public static void main(String[] args) {
		Integer[] i = {1,2,3,4,5}; //這裏不能用int類型數組,如果用int類型
		Integer[] i2 = fun(i);	   //這裏就會報錯,因爲T一定是派生於Object類的
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章