2013年5月10日星期五

java泛型通配符-协变与逆变

From Evernote:

java泛型通配符-协变与逆变

Clipped from: http://arron-li.iteye.com/blog/673783

周末研究了下java泛型,关于泛型通配符的协变与逆变问题,题目如下:

  •  题目要求:创建一个泛型类Generic1<T>,它只有一个方法,将接受一个T类型的参数。创建第二个泛型类Generic2<T>,它也只有一个方法,将返回类型T的参数。编写一个泛型方法,它具有一个调用第一个泛型类的方法的逆变参数。编写第二个泛型方法,它具有一个调用第二个泛型类的方法的协变参数。
  • 实例代码如下:

 

Java代码  
  1. package generics.exercises;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import typeinfo.pets.Dog;  
  7.   
  8. public class ContraVarianceAndCovariant {  
  9.     static class Generic1Sup<T> {  
  10.     }  
  11.   
  12.     static class Generic1<T> extends Generic1Sup<T> {  
  13.         void setT(T t) {  
  14.         }  
  15.     }  
  16.   
  17.     static class Generic1Sub<T> extends Generic1<T> {  
  18.     }  
  19.   
  20.     static class Generic2Sup<T> {  
  21.     }  
  22.   
  23.     static class Generic2<T> extends Generic2Sup<T> {  
  24.         T getT(T t) {  
  25.             return t;  
  26.         }  
  27.     }  
  28.   
  29.     static class Generic2Sub<T> extends Generic2<T> {  
  30.     }  
  31.   
  32.     static <T> void writeWithWildcard(List<? super T> list, T item) {  
  33.         list.add(item);  
  34.     }  
  35.   
  36.     static <T> T readCovariant(List<? extends T> list) {  
  37.         return list.get(0);  
  38.     }  
  39.   
  40.     static List<Generic1<Dog>> dogs = new ArrayList<Generic1<Dog>>();  
  41.     static List<Generic1Sup<Dog>> dogsSup = new ArrayList<Generic1Sup<Dog>>();  
  42.     static List<Generic1Sub<Dog>> dogsSub = new ArrayList<Generic1Sub<Dog>>();  
  43.   
  44.     static List<Generic2<Dog>> dogs2 = new ArrayList<Generic2<Dog>>();  
  45.     static List<Generic2Sup<Dog>> dogs2Sup = new ArrayList<Generic2Sup<Dog>>();  
  46.     static List<Generic2Sub<Dog>> dogs2Sub = new ArrayList<Generic2Sub<Dog>>();  
  47.   
  48.     static void f1() {  
  49.         writeWithWildcard(dogs, new Generic1<Dog>());  
  50.         writeWithWildcard(dogsSup, new Generic1<Dog>());  
  51.         // ! writeWithWildcard(dogsSub, new Generic1<Dog>());  
  52.         Generic1<Dog> generic1 = dogs.get(0);  
  53.         generic1.setT(new Dog("dog1"));  
  54.         System.out.println(generic1);  
  55.     }  
  56.   
  57.     static void f2() {  
  58.         Generic2<Dog> generic2 = readCovariant(dogs2);  
  59.         generic2 = (Generic2<Dog>) readCovariant(dogs2Sup);  
  60.         generic2 = readCovariant(dogs2Sub);  
  61.         generic2.getT(new Dog("dog2"));  
  62.         System.out.println(generic2);  
  63.     }  
  64.   
  65.     static class CovariantReader<T> {  
  66.         T readCovariant(List<? extends T> list) {  
  67.             return list.get(0);  
  68.         }  
  69.     }  
  70.   
  71.     static void f3() {  
  72.         CovariantReader<Generic2<Dog>> fruitReader = new CovariantReader<Generic2<Dog>>();  
  73.         Generic2<Dog> generic2 = fruitReader.readCovariant(dogs2);  
  74.         // ! generic2 = fruitReader.readCovariant(dogs2Sup);  
  75.         generic2 = fruitReader.readCovariant(dogs2Sub);  
  76.         generic2.getT(new Dog("dog2"));  
  77.     }  
  78. }  

 感兴趣的读者可以研究下,为题目提供更好的解决方案。

没有评论: