canvas教程

【第九章.泛型(6)

字号+ 作者:H5之家 来源:H5之家 2017-08-16 15:00 我要评论( )

为了让编译器可以准确地判断出泛型方法中类型形参的类型,不要制造迷惑,一旦系统迷惑,就是你错了!如下: 1 import java.util.Collection; 2 import java.util.List; 3 import java.util.ArrayList; 4 5 public c

  为了让编译器可以准确地判断出泛型方法中类型形参的类型,不要制造迷惑,一旦系统迷惑,就是你错了!如下:

1 import java.util.Collection; 2 import java.util.List; 3 import java.util.ArrayList; 4 5 public class ErrorTest{ 6 //声明一个泛型方法,该泛型方法中带一个T类型形参 7 static <T> void test(Collection<T> from, Collection<T> to){ 8 for(T ele : from){ 9 to.add(ele); 10 } 11 } 12 13 public static void main(String[] args){ 14 List<Object> ao = new ArrayList<>(); 15 List<String> as = new ArrayList<>(); 16 //下面代码将产生编译错误 17 test(as, ao); 18 } 19 } View Code

  上面程序调用test()方法传入两个实际参数,as是List<String>,ao是List<Object>,与test(Collection<T> a, Collection<T> c)相比,编译器无法正确识别T所代表的实际类型。

  虽然String是Object的子类,但是集合中没有使用类型形参的上限,所以T只能代表String或Object类中的一个,不能代表两个。

  改写为如下程序:

1 import java.util.Collection; 2 import java.util.List; 3 import java.util.ArrayList; 4 5 public class ErrorTest{ 6 //声明一个泛型方法,该泛型方法中带一个T类型形参 7 static <T> void test(Collection<? extends T> from, Collection<T> to){ 8 for(T ele : from){ 9 to.add(ele); 10 } 11 } 12 13 public static void main(String[] args){ 14 List<Object> ao = new ArrayList<>(); 15 List<String> as = new ArrayList<>(); 16 //下面代码将产生编译错误 17 test(as, ao); 18 } 19 } View Code

    程序中test(Collection<? extends T> from, Collection<T> to):只要前一个Collection集合里的元素类型是后一个Collection集合里元素类型的子类即可。

  那么什么时候使用泛型方法?什么时候使用类型通配符?

  泛型方法和类型通配符的区别:

    大多数时候都可以使用泛型方法来代替类型通配符。如,Java的Collection接口中的两个方法:

1 public interface Collection<E>{ 2 boolean containsAll(Collection<?> c); 3 boolean addAll(Collection<? extends E> c); 4 } View Code

    上面集合中两个方法的形参都采用了类型通配符的形式,也可以采用泛型方法的形式:

1 public interface Collection<E>{ 2 <T> boolean containsAll(Collection<T> c); 3 <T extends E>boolean addAll(Collection<T> c); 4 } View Code

    若方法中一个形参(a)的类型或返回值类型依赖于另一个形参(b)的类型,则形参(b)的类型声明不应该是通配符,如:

      public static <T> void copy(List<T> dest, List<? extends T> src) { ... }//这里dest形参的类型不能是通配符?,否则两个形参类型模糊。

    上面的代码可以改为如下:

      public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... }//正是因为这里的S类型形参只使用了一次,所以没有存在的必要,直接用类型通配符代替即可

  Java7的“菱形”语法与泛型构造器:

    泛型构造器:

1 class Foo{ 2 public <T> Foo(T t){ 3 System.out.println(t); 4 } 5 } 6 7 public class GenericConstructor{ 8 public static void main(String[] args){ 9 //泛型构造器中的T参数为String 10 new Foo("疯狂Java讲义"); 11 //泛型构造器中的T参数为Integer 12 new Foo(200); 13 //显示指定泛型构造器中的T参数为String 14 //传给Foo构造器的实参也是String对象,完全正确 15 new <String> Foo("疯狂Android讲义"); 16 //显示指定泛型构造器的T参数为String 17 //但传给Foo构造器的实参是Double独享,下面代码是错误的 18 new <String> Foo(12.3); 19 } 20 } View Code

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 使用jquery-qrcode生成二维码

    使用jquery-qrcode生成二维码

    2017-08-16 14:01

  • python学习笔记14--用Tkinter实现GUI编程

    python学习笔记14--用Tkinter实现GUI编程

    2017-08-15 17:00

  • Canvas名侦探柯南-canvas练习,canvas-canvas

    Canvas名侦探柯南-canvas练习,canvas-canvas

    2017-08-12 14:00

  • 读javascript高级程序设计04-canvas

    读javascript高级程序设计04-canvas

    2017-08-06 11:01

网友点评
/