JDK
令我們期待很久
可是當他發布的時候卻更換版本號為
這說明Java已經有大幅度的變化
本文將講解JDK
支持的新功能
Java的泛型
Java泛型
其實Java的泛型就是創建一個用類型作為參數的類
就象我們寫類的方法一樣
方法是這樣的method(String str
String str
)
方法中參數str
str
的值是可變的
而泛型也是一樣的
這樣寫class Java_Generics<K
V>
這裡邊的K和V就象方法中的參數str
和str
也是可變
泛型通配符
下面我們先看看這些程序
//Code list
void TestGen
Medthod
(List l) {
for (Object o : l)
System
out
println(o)
}
看看這個方法有沒有異議
這個方法會通過編譯的
假如你傳入String
就是這樣List<String>
接著我們調用它
問題就出現了
我們將一個List<String>當作List傳給了方法
JVM會給我們一個警告
說這個破壞了類型安全
因為從List中返回的都是Object類型的
而讓我們再看看下面的方法
//Code list
void TestGen
Medthod
(List<String>l) {
for (Object o : l)
System
out
println(o)
}
因為這裡的List<String>不是List<Object>的子類
不是String與Object的關系
就是說List<String>不隸屬於list<Object>
他們不是繼承關系
所以是不行的
這裡的extends是表示限制的
類型通配符是很神奇的
List<?>這個你能為他做什麼呢?怎麼都是
?
它似乎不確定
他總不能返回一個?作為類型的數據吧
是啊他是不會返回一個
?
來問程序員的?JVM會做簡單的思考的
看看代碼吧
更直觀些
//code list
List<String>l
= new ArrayList<String>()
li
add(
String
)
List<?>l
= l
;
System
out
println(l
get(
))
這段代碼沒問題的
l
get(
)將返回一個Object
編寫泛型類要注意
) 在定義一個泛型類的時候
在
<>
之間定義形式類型參數
例如
class TestGen<K
V>
其中
K
V
不代表值
而是表示類型
) 實例化泛型對象的時候
一定要在類名後面指定類型參數的值(類型)
一共要有兩次書寫
例如
TestGen<String
String>t=new TestGen<String
String>()
) 泛型中<K extends Object>
extends並不代表繼承
它是類型范圍限制
泛型與數據類型轉換
消除類型轉換
上面的例子大家看到什麼了
數據類型轉換的代碼不見了
在以前我們經常要書寫以下代碼
如
//code list
import Java
util
Hashtable;
class Test {
public static void main(String[] args) {
Hashtable h = new Hashtable()
h
put(
key
value
)
String s = (String)h
get(
key
)
System
out
println(s)
}
}
這個我們做了類型轉換
是不是感覺很煩的
並且強制類型轉換會帶來潛在的危險
系統可能會拋一個ClassCastException異常信息
在JDK
中我們完全可以這麼做
這裡我們使用泛化版本的HashMap
這樣就不用我們來編寫類型轉換的代碼了
類型轉換的過程交給編譯器來處理
是不是很方便
而且很安全
上面是String映射到String
也可以將Integer映射為String
只要寫成HashTable<Integer
String>h=new HashTable<Integer
String>()
h
get(new Integer(
))返回value
果然很方便
自動解包裝與自動包裝的功能
從上面有沒有看到有點別扭啊
h
get(new Integer(
))這裡的new Integer(
)
好煩的
在JDK
之前我們只能忍著了
現在這種問題已經解決了
請看下面這個方法
我們傳入一個int這一基本型別
然後再將i的值直接添加到List中
其實List是不能儲存基本型別的
List中應該存儲對象
這裡編譯器將int包裝成Integer
然後添加到List中去
接著我們用List
get(
)
來檢索數據
並返回對象再將對象解包裝成int
恩
JDK
給我們帶來更多方便與安全
//Code list
public void autoBoxingUnboxing(int i) {
ArrayList<Integer>L= new ArrayList<Integer>()
L
add(i)
int a = L
get(
)
System
out
println(
The value of i is
+ a)
}
限制泛型中類型參數的范圍
也許你已經發現在code list
中的TestGen<K
V>這個泛型類
其中K
V可以是任意的型別
也許你有時候呢想限定一下K和V當然范圍
怎麼做呢?看看如下的代碼
//Code list
class TestGen
<K extents String
V extends Number>
{
private V v=null;
private K k=null;
public void setV(V v){
this
v=v;
}
public V getV(){
return this
v;
}
public void setK(K k){
this
k=k;
}
public V getK(){
return this
k;
}
public static void main(String[] args)
{
TestGen
<String
Integer>t
=new TestGen
<String
Integer>()
t
setK(new String(
String
))
t
setV(new Integer(
))
System
out
println(t
getK())
System
out
println(t
getV())
}
}
上邊K的范圍是<=String
V的范圍是<=Number
注意是
<=
對於K可以是String的
V當然也可以是Number
也可以是Integer
Float
Double
Byte等
看看下圖也許能直觀些請看上圖A是上圖類中的基類
A
A
分別是A的子類
A
有
個子類分別是A
_
A
_
然後我們定義一個受限的泛型類class MyGen<E extends A
>
這個泛型的范圍就是上圖中蘭色部分
這個是單一的限制
你也可以對型別多重限制
如下
class C<T extends Comparable<? super T>& Serializable>
我們來分析以下這句
T extends Comparable這個是對上限的限制
Comparable<super T>這個是下限的限制
Serializable是第
個上限
一個指定的類型參數可以具有一個或多個上限
具有多重限制的類型參數可以用於訪問它的每個限制的方法和域
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25837.html