作者:程式魚
連結:https://www。jianshu。com/p/95f349258afb
1。 先解釋下泛型概念
泛型是Java SE 1。5的新特性,泛型的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。這種引數型別可以用在類、介面和方法的建立中,分別稱為泛型類、泛型介面、泛型方法。Java語言引入泛型的好處是安全簡單。
在Java SE 1。5之前,沒有泛型的情況的下,透過對型別Object的引用來實現引數的“任意化”,“任意化”帶來的缺點是要做顯式的強制型別轉換,而這種轉換是要求開發者對實際引數型別可以預知的情況下進行的。對於強制型別轉換錯誤的情況,編譯器可能不提示錯誤,在執行的時候才出現異常,這是一個安全隱患。
泛型的好處是在編譯的時候檢查型別安全,並且所有的強制轉換都是自動和隱式的,以提高程式碼的重用率。
以上內容摘自百度百科
舉個栗子:
Box類定義為一個泛型類
public
class
Box
<
T
>
{
private
T
object
;
public
void
set
(T
object
) {
this
。
object
=
object
; }
public
T
get
() {
return
object
; }
}
建立一個Box物件,不帶泛型引數,發現獲取物件的時候需要強制轉換
Box box2 =
new
Box();
box2。
set
(
new
Apple());
Apple apple = (Apple) box2。
get
();
建立一個Box物件,帶泛型引數,獲取物件的時候就不需要強制轉換
Box
new
Box
box。
set
(
new
Apple());
Apple apple = box。
get
();
總結下泛型的好處就是
省去了強制轉換,可以在編譯時候檢查型別安全,可以用在類,方法,介面上
但是我們定義泛型類,泛型方法,泛型介面的時候經常會碰見很多不同的萬用字元T,E,K,V等等,這些萬用字元又都是什麼意思呢?繼續往下看
2。 下來說說泛型萬用字元T,E,K,V區別
這些全都屬於java泛型的萬用字元,剛開始我看到這麼多萬用字元,一下暈了,這幾個其實
沒什麼區別
,只不過是一個約定好的程式碼,也就是說
使用大寫字母A,B,C,D……X,Y,Z定義的,就都是泛型,把T換成A也一樣,這裡T只是名字上的意義而已
?
表示不確定的java型別
T (type)
表示具體的一個java型別
K V (key value)
分別代表java鍵值中的Key Value
E (element)
代表Element
舉個栗子:
public
class
Test
public
List
list
=
new
ArrayList
public
static
void
main
(String[] args)
{
Test
new
Test
test。
list
。add(
“hello”
);
System。out。println(test。
list
);
}}
和
public
class
Test
public
list
=
new
ArrayList();
public
static
void
main
(String[] args)
{
Test
new
Test
test。
list
。add(
“hello”
);
System。out。println(test。
list
);
}}
將T換成了A,在執行效果上是沒有任何區別的,只不過我們約定好了T代表type,所以還是
按照約定規範來比較好
,增加了程式碼的可讀性。
如果要定義
多個
泛型引數,比如說兩個泛型引數
很典型的一個栗子是Map的key,value泛型,我們也可以定義一個這樣的
public
interface
Mymap
<
K
,
V
>
{
public
K
getKey
()
;
public
V
getValue
()
;
}
public
class
MymapImpl
<
K
,
V
>
implements
Mymap
<
K
,
V
>
{
private
K key;
private
V value;
public
MymapImpl
(K key, V value)
{
this
。key = key;
this
。value = value;
}
public
K
getKey
()
{
return
key; }
public
V
getValue
()
{
return
value; }
}
下來就可以傳入任意型別,建立例項了,不用轉化型別
Mymap<
String
,
Integer
> mp1=
new
MymapImpl<
String
,
Integer
>(
“Even”
,
8
);
Mymap<
String
,
String
> mp2=
new
MymapImpl<
String
,
String
>(
“hello”
,
“world”
);
Mymap<
Integer
,
Integer
> mp3=
new
MymapImpl<
Integer
,
Integer
>(
888
,
888
);
如果要定義
超過兩個,三個或三個以上
的泛型引數可以使用
T1, T2, …, Tn
,像這樣子
public
class
Test
public
void
(T1 t1,T2 t2,T3 t3)
{
System。out。println(t1。getClass());
System。out。println(t2。getClass());
System。out。println(t3。getClass());
}
}
3。 接下來說說Object ? T區別
ArrayList
al=new ArrayList
();指定集合元素只能是T型別
ArrayList al=new ArrayList();集合元素可以是任意型別,這種沒有意義,一般是方法中,只是為了說明用法
ArrayList al=new ArrayList();
泛型的限定:
? extends E:接收E型別或者E的子型別。
? super E:接收E型別或者E的父型別
Object和T不同點在於,Object是一個實打實的類,並沒有泛指誰,而T可以泛指Object,比方
public void printList(Listlist){}
方法中可以傳入
List list型別引數,也可以傳入Listlist型別引數,但是public void printList(List list){}就只可以傳入List list型別引數,因為Object型別並沒有泛指誰,是一個確定的型別?和T區別是?是一個不確定類,?和T都表示不確定的型別 ,但如果是T的話,函數里面可以對T進行操作,比方 T car = getCar(),而不能用?car = getCar()。
Listlist