Archive

Posts Tagged ‘泛型’

java特性-泛型

March 28th, 2008 No comments

1:泛型1.1 list中使用类型安全
定义A:List list = new LinkedList()
尖括号中的类型必须是Object,不能是int等原始类型;一旦list被定义了特定的类型,那么使用add方法时,放入list的对象必定是你定义list时的类型对象
定义B: List list = new LinkedList();
可以添加子类对象:list.add(new Integer(1))或list.add(new Float(2))
1.2 map中使用类型安全
定义:

1
2
3
4
        Map<Integer, Integer> mapA = new HashMap<Integer, Integer>();
        Map<String, String> mapB = new HashMap<String, String>();
        Map<String, Object> mapC = new HashMap<String, Object>();
        Map<Long, String> mapD = new HashMap<Long, String>();

1.3 Iterating Over Parameterized Types
看一下代码A

1
2
3
4
5
6
7
8
        List<String> list = new LinkedList( );
        list.add("hello");
        list.add("world");
        //for (Iterator i = list.iterator( ); i.hasNext(); ) {
        for (Iterator<String> i = list.iterator(); i.hasNext(); ) {
          String s = i.next();
          System.out.println(s);
        }

如果for语句的定义是注释那句的话,编译报错;如果之前的collections是参数化的,那么这里的iterator必须也要参数化.
看一下代码B

1
2
3
4
5
6
7
8
        List list = new LinkedList( );
        list.add("hello");
        list.add("world");
        list.add(1);
        for (Iterator<String> i = list.iterator(); i.hasNext(); ) {
          String s = i.next();
          System.out.println(s);
        }

以上代码虽然在编译期通过,但在运行期发生严重的错误:java.lang.ClassCastException,所以如果你想使用参数化的iterator,那么你就要参数化你的collections
1.4 Accepting Parameterized Types as Arguments
看一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
   public static void main(String[] args) {
        List list = new LinkedList( );
        list.add("hello");
        list.add("world");
        list.add(1);
        printListOfString(list);
    }
 
    public static void printListOfString(List<String> list) {
        for(Iterator<String> iterator = list.iterator();iterator.hasNext();) {
            System.out.println(iterator.next());
        }
    }

编译时没有错误,运行时报ClassCastException,所以调用类型安全的方法时,确保你传入的parameter是类型安全的.例子中传入的list最好申明为:List,以面运行期错误.
1.5 Returning Parameterized Types
看一下代码

1
2
3
4
5
6
7
8
9
10
11
   public static void main(String[] args) {
        List list = getListOfStrings();
        //List<String> list = getListOfStrings();
    }
 
    public static List<String> getListOfStrings() {
        List<String> list = new LinkedList<String>();
        list.add("Hello");
        list.add("World");
        return list;
    }

1.6 Using Parameterized Types as Type Parameters
看一下代码

1
2
3
        Map<String, List<String>> mapA = new HashMap<String, List<String>>();
        Map<String, List<List<int[]>>> mapB;
        Map<String, List<int[]>> mapC;

注意mapB和mapC的区别
1.7 Generics and Type Conversions
看一下代码A:

1
2
3
        LinkedList<Float> floatList = new LinkedList<Float>();
        List<Float> moreFloats = floatList;                          //正确的转换
        LinkedList<Number> numberList = floatList;            //错误的转换

这个错误我也看了好久才明白:
1:类型转换只允许基础类,而不是类型安全所申明的类,这也是为了防止运行期的错误
2:类型安全是在编译期做处理,做类型安全的检查,一定编译通过,真正的代码将是没有类型安全定义的,如:
List floatList = new LinkedList();
在编译后就成:
List floatList = new LinkedList();
所以只做基础类别List的转换比parameter type的转换更合理
看一下代码B:

1
2
3
4
        List<Integer> ints = new LinkedList<Integer>();
        List oldList = ints;
        oldList.add("Hello World");
        Integer i = ints.get(0);

这里ints转成了无类型定义的list,虽然编译通过,但是runtime时发生ClassCastException,反编译.class文件看到:

1
2
3
4
        List ints = new LinkedList();
        List oldList = ints;
        oldList.add("Hello World");
        Integer i = (Integer)ints.get(0);

从上而知:所谓类型安全自是为了开发者方便,容易检查错误,在编译后,运行时,jvm自动帮助做了类型转换
1.8 Using Type Wildcards
看一下代码

1
2
3
4
5
6
7
8
9
10
11
12
    public static void main(String[] args) {
        List<TypeWildcards> list = new ArrayList<TypeWildcards>();
        TypeWildcards a = new TypeWildcards();
        list.add(a);
        printList(list);
    }
 
    public static void printList(List<?> list){
        for (Iterator<?> i = list.iterator(); i.hasNext();) {
            System.out.println(i.next().toString());
        }
    }

1.9 Writing Generic Types
看一下代码

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
  import java.util.ArrayList;
  import java.util.List;
 
  public class Box<A> {
      public static void main(String[] args) {
          Box<Integer> box = new Box<Integer>();
          box.add(1);
      }
      protected List<A> contents;
      public Box(){
          contents = new ArrayList<A>();
      }
      public int getSize() {
          return contents.size();
      }
      public boolean isEmpty() {
          return (contents.size() == 0);
      }
      public void add(A o) {
          contents.add(o);
      }
      public A grab() {
          if (!isEmpty()) {
              return contents.remove(0);
          } else {
              return null;
          }
      }
  }

代码中的A可以是其他的英文字符,大小写均可
1.10 Restricting Type Parameters
看一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
  import java.util.Iterator;
  public class NumberBox<A extends Number> extends Box<A> {
      public NumberBox(){
          super();
      }
      public double sum() {
          double total = 0;
          for (Iterator<A> i = contents.iterator(); i.hasNext();) {
              total = total + i.next().doubleValue();
          }
          return total;
      }
  }
Categories: technic Tags: , ,