天天看点

优先考虑类型安全的异构容器

      一般情况下,泛型最通常应用于集合,如set和Map,以及单元素的容器,如ThreadLocal等。在这些语法中一般情况下,这些容器都被充当被参数化了的容器,意味着每个容器只能有一个或者多个固定数目的类型参数。如一个Set只有一个类型参数,用于表示元素类型。一个Map有两个类型参数,表示它的键和值类型。(个人认为类型参数就是指定了类型的参数。这也是泛型的意义所在)

      但是有时候我们可能需要更多的灵活性,比如数据库行可以有任意多的列,每个列的类型可能不一样,如果能以类型安全的方式访问所有列就好了。目前,有一种方法可以实现,就是将键值(key)进行参数化而不是对整个容器进行参数化。然后将参数化的键值提交给容器,来插入或者获取值。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

public

class

Favorite {

private

Map<Class<?>,Object>  map = 

new

HashMap<Class<?>, Object>();

private

Map<List<?>,Object>  map2 = 

new

HashMap<List<?>, Object>();

public

<E> 

void

add(Class<E> type,E instance) {

if

(type!=

null

) {

map.put(type, instance);

}

}

public

<E> 

void

add(List<E> type,E instance) {

if

(type!=

null

) {

map2.put(type, instance);

}

}

public

<E> E 

get

(Class<E> type) {

Object 

object

= map.

get

(type);

return

type.cast(

object

);

}

public

static

void

main(String[] args) {

Favorite f = 

new

Favorite();

f.add(String.

class

"string"

);

//可以插入String类型

f.add(Integer.

class

, Integer.valueOf(123));

//可以插入int类型

f.add(

new

ArrayList<String>(), 

"String"

);

//可以插入String类型

f.add(

new

ArrayList<Integer>(), 123);

//可以插入int类型

String s1 = f.

get

(String.

class

);

Integer i = f.

get

(Integer.

class

);

System.

out

.println(s1);

System.

out

.println(i);

}

}

  

上面的例子就是实现了一个可以指定多个类型的插入和读取,且是类型安全的。

这个例子需要注意的是

private Map<Class<?>,Object>  map = new HashMap<Class<?>, Object>();

每个Favorite实例都得到一个被称作map的私有      
Map<Class<?>,Object> 
    的支持。开始的时候,我们可能会将不能将任何东西放入到这个Map中去,因为其实无限制通配符,但是其实事实正好相反,我们可以删除任意类型的数据,原因是因为这个通配符是嵌套的,它不是属于通配符类型的Map的类型,而是他的key的类型。由此可见,每个键都可以有一个不同的参数化类型,本示例中Class<String> Class<Integer>。