Java程序低手之关于泛型(Generic)
虽然一直以来,Java都提供了强制类型转换,但是那确实是Java的弱点,因为你是在取数据的时候才保证了类型安全(Type-safe),而不是在存储数据的时候就做好这项工作,Java5提供了Generic来保证这项工作,从而提高了Java的类型安全(Type-safe)。
使用Type-Safe的List
只接受String类型的List申明代码如下:
1 List<String> list=new LinkedList<String>();
2 list.add("hello");
list只能接受String类型,如果你试图传入其他的类型那么,会产生编译错误。当然其中的String可以换成其他的类型如Integer,Boolean或者自己申明的类类型(class type),但不可以是元类型(primitive type)。也许你会担心int与Integer之间的转换,但是当你见识到autoboxing之后,你就会释怀。
其他的collection class也如list一样使用Generic来保证Type-Safe
使用Type-Safe的Map
list接受了一个Generic变量,而Map则需要接受两个,代码如下:
1 Map<String,String> map=new HashMap<String,String>();
2 map.put("key", "value");
其中的String与上面list之中的一样。
Interating Over Parameterized Type 迭代器中的参数类型(泛型)
1 List<String> list=new LinkedList<String>();
2 list.add("hello");
3 list.add("word");
4
5 for(Iterator i=list.iterator();i.hasNext();){
6 String s=(String) i.next();//这里必须进行强制类型转换,因为Iterator中是Object类型的对象
7 }
8
9 for(Iterator<String> i=list.iterator();i.hasNext();){
10 String s= i.next();//这里不用进行强制转换,因为Iterator中在输入的时候已经成为了String对象
11 }
对比上面的5和9行会发现为什么6和10行不一样。
来看下面一段代码,看看你发现了什么?
1 public List<String> testGenericMethod(List<String> list){
2 list.add("hello");
3 list.add("word");
4 Map<String,List<String>> map=new HashMap<String,List<String>>();
5 map.put("helloword", list);
6 return list;
7 }
事实上,Generic的Parameterized Type(参数化类型)可以作为参数:行1,作为返回类型:行1,作为类型参数:行4.
你可能也知道Lint(棉絮)警告,虽然作为程序员,我们是一贯的不管警告,但是规避警告总是好的。所以你可以这样写代码,来减少警告:
1 List<Object> list=new LinkedList<Object>();
Generic与类型转换
在做类型转换的时候,通常只转换基础类型,而不转换Generic类型,如下所示:
1 LinkedList<Float> list=new LinkedList<Float>();
2 List<Float> list2=list;//这个是允许的
3 LinkedList<Number> list3=list;//这个存在编译错误,具体的不再详细解释
类型通配符
有时候我们不知道某个代码提供给别人后,他们会怎么样使用,所以需要一个通配符,如下所示
1 public void testGenericMethod(List<?> list){
2 for(Iterator<?> i=list.iterator();i.hasNext();)
3 System.out.println(i.next().toString());
4 }
如果去掉其中的<?>通配符,则往往会产生unchecked警告
写一个Generic
好了,我想我们可以写一个Generic了,不用太复杂。
1 class A<E>{
2 private List<E> list;
3 public A(){
4 list=new ArrayList<E>();
5 }
6 public E add(E ele){
7 list.add(ele);
8 return ele;
9 }
10 }
其中的E是用来代表一个类型参数
限制类型参数
有时候可能你并不想所有的类型作为类型参数,那怎么办呢?看下面一段代码:
1 class A<E extends Number>{
2 private List<E> list;
3 public A(){
4 list=new ArrayList<E>();
5 }
6 public E add(E ele){
7 list.add(ele);
8 return ele;
9 }
10 }
与原来的相比较在E后面多出了 extends 语句,这样传进来的类型就必须是Number或者其子类型了。
以上是 Java程序低手之关于泛型(Generic) 的全部内容, 来源链接: utcz.com/z/393552.html