java中的泛型

来源:互联网 发布:淘宝汽车贴膜 编辑:程序博客网 时间:2024/06/09 22:44

Java

中的泛型

 

 

JDK1.5

 

令我们期待很久

,

可是当他发布的时候却更换版本号为

5.0

。这说明

Java

已经有大

幅度的变化。本文将讲解

JDK5.0

支持的新功能

-----Java

泛型

 

 

 

1

Java

泛型

 

 

 

 

其实

Java

的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法

是这样的

method

(

String

 str1,String str2 ),

方法中参数

str1

str2

的值是可变的。而

泛型也是一样的,这样写

class

 Java_Generics

K,V

>,这里边的

K

V

就象方法中的参

str1

str2,

也是可变。下面看看例子:

 

//

code

 

list

 1 

import

 Java.util.Hashtable; 

class TestGen0

K,V

 

public

 Hashtable

K,V

 h=new Hashtable

K,V

(); 

 

public 

void

 put(K k, V v) { 

 

 

h.put(k,v); 

 

 

public V get(K k) { 

 

 

return

 h.get(k); 

 

 

public 

static

 void main(String args[]){ 

 

 

TestGen0

String,String

 t=new TestGen0

String,String

(); 

 

 

t.put("key", "

value

"); 

 

 

String s=t.get("key"); 

 

 

System.out.println(s); 

 

 

 

 

正确输出

:value 

 

 

 

这只是个例子(

Java

中集合框架都泛型化了,这里费了

2

遍事

.

),不过看看是不是创

建一个用类型作为参数的类,参数是

K

V

,传入的“值”是

String

类型。这个类他没有特

定的待处理型别,

以前我们

定义

好了一个类,

在输入输入参数有所固定,

是什么型别的有要

求,但是现在编写程序,

完全可以不制定参数的类型,具体用的时候来确定,增加了程序的

通用性,像是一个

模板

 

 

 

 

呵呵,类似

C++

的模板(类似)。

 

 

 

 

1.1. 

泛型通配符

 

 

 

 

下面我们先看看这些程序:

 

//Code list 2 

void TestGen0Medthod1(List l) { 

 

for (

Object

 o : l) 

 

 

System.out.println(o); 

 

 

 

看看这个方法有没有异议,

这个方法会通过编译的,

假如你传入

String

就是这样

List

String

>。

 

 

 

 

接着我们调用它

,

问题就出现了,我们将一个

List

String

>当作

List

传给了方法,

JVM

会给我们一个警告,

说这个破坏了

类型安全

因为从

List

中返回的都是

Object

类型的,

而让我们再看看下面的方法。

 

//Code list 3 

void TestGen0Medthod1(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 4 

List

String

 l1 = new ArrayList

String

(); 

li

.

add

(

String

); 

List

?

 l2 = l1; 

System.out.println(l1.get(0)); 

 

 

 

这段代码没问题的,

l1.get(0)

将返回一个

Object

 

 

 

 

1.2. 

编写泛型类要注意:

 

 

 

 

1) 

在定义一个泛型类的时候,

 

<>”

之间定义形式类型参数,

例如:

class 

TestGen

K,V

>”,其中“

K

 , 

V

”不代表值,而是表示类型。

 

 

 

 

2) 

实例

化泛型对象的时候,一定要在类名后面指定类型参数的值(类型),一共要有

两次书写。例如:

 

 

TestGen

String,String

 t=new TestGen

String,String

()

 

 

 

 

3) 

泛型中<

K extends Object

,extends

并不代表继承,它是类型范围限制。

 

2

、泛型与数据类型转换

 

 

 

 

2.1. 

消除类型转换

 

 

 

 

上面的例子大家看到什么了,

数据类型转换的代码不见了。

在以前我们经常要书写以下

代码,如:

 

//code list 5 

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

异常信息。在

JDK5.0

中我们完全可以这么做,如:

 

//code list 6 

import Java.util.Hashtable; 

class Test { 

 

public static void main(String[] args) { 

 

 

Hashtable

String,Integer

 h = new Hashtable

String,Integer

 (); 

 

 

h.put("key", new Integer(123)); 

 

 

int s = h.get("key").intValue(); 

 

 

System.out.println(s); 

 

 

 

 

这里我们使用泛化版本的

HashMap,

这样就不用我们来编写类型转换的代码了,类型转

换的过程交给编译器来处理,是不是很方便,而且很安全。上面是

String

映射到

String

也可以将

Integer

映射为

String

,只要写成

HashTable

Integer,String

 h=new 

HashTable

Integer,String

();h.get(new Integer(0))

返回

value

。果然很方便。

 

 

 

 

2.2 

自动解包装与自动包装的功能

 

 

 

 

从上面有没有看到有点别扭啊,

h.get(new Integer(123))

这里的

new Integer(123);

好烦的,在

JDK5.0

之前我们只能忍着了,现在这种问题已经解决了,请看下面这个方法。

我们传入一个

int

这一基本型别,

然后再将

i

的值直接添加到

List

中,

其实

List

是不能储

存基本型别的,

List

中应该存储对象,

这里编译器将

int

包装成

Integer

然后添加到

List

中去。

接着我们用

List.get(0);

来检索数据,

并返回对象再将对象解包装成

int

恩,

JDK5.0

给我们带来更多方便与安全。

 

//Code list 7 

public void autoBoxingUnboxing(int i) { 

 

ArrayList

Integer

 L= new ArrayList

Integer

(); 

 

L.add(i); 

 

int a = L.get(0); 

 

System.out.println("The value of i is " + a); 

 

 

 

2.3 

限制泛型中类型参数的范围

 

 

 

 

也许你已经发现在

code list 1

中的

TestGen

K,V

>这个泛型类

,

其中

K,V

可以是任意

的型别。也许你有时候呢想限定一下

K

V

当然范围,怎么做呢?看看如下的代码:

 

//Code list 8 

class TestGen2

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) 

 

 

 

TestGen2

String,Integer

 t2=new TestGen2

String,Integer

(); 

 

 

t2.setK(new String("String")); 

 

 

t2.setV(new Integer(123)); 

 

 

System.out.println(t2.getK()); 

 

 

System.out.println(t2.getV()); 

 

 

 

 

上边

K

的范围是<

=String 

V

的范围是<

=Number

注意是

“<

=

,

对于

K

可以是

String

的,

V

当然也可以是

Number

也可以是

Integer,Float,Double,Byte

等。

看看下图也许能直

观些请看上图

A

是上图类中的基类,

A1

A2

分别是

A

的子类,

A2

2

个子类分别是

A2_1

A2_2

 

 

 

 

然后我们定义一个受限的泛型类

class MyGen

E extends A2

,

这个泛型的范围就是

上图中兰色部分。

 

 

 

 

这个是单一的限制,你也可以对型别多重限制,如下:

 

class C

T extends Comparable

? super T

 & Serializable

 

 

 

 

我们来分析以下这句,

T extends Comparable

这个是对上限的限制,

Comparable

 

super 

T

>这个是下限的限制,

Serializable

是第

2

个上限。一个指定的类型参数可以具有

一个或多个上限。具有多重限制的类型参数可以用于访问它的每个限制的方法和域。

 

 

 

 

2.4. 

多态方法

 


0 0