canvas教程

【第九章.泛型

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

第九章.泛型 - lanshanxiao, 泛型入门: Java集合有个缺点:把一个对象“丢进”集合里之后,集合就会“忘记”这个对象的数据类型,当再次取出该对象时,该对象的

有网友碰到过这样的问题:第九章.泛型 - lanshanxiao,问题详细内容为:挺不错的博文:第九章.泛型 - lanshanxiao,我搜你通过互联网收集了相关的一些解决方案,希望对有过相同或者相似问题的网友提供帮助,具体如下:

泛型入门:

  Java集合有个缺点:把一个对象“丢进”集合里之后,集合就会“忘记”这个对象的数据类型,当再次取出该对象时,该对象的编译类型就变成了Object类型(其运行时类型没变)。

  Java集合之所以被设计成这样,是因为集合的设计者不知道我们会用集合来保存什么类型的对象,所以把集合设计成可以保存任何类型的对象,只要求有很好的通用性。但这样

   做带来了两个问题:

    1.集合对元素类型没有任何限制,这样引发一些问题。如:想创建一个只能保存Dog对象的集合,但程序也可以轻易的将Cat对象“丢”进去,所以可能引发异常

    2.由于把对象“丢进”集合时,集合丢失了对象的状态信息,集合只知道盛装它的是Object,因此取出集合元素后通常还需要进行强制类型转换。这种强制转换既增加了编

     程的复杂度,也可能引发ClassCastException异常。

  编译时不检查类型的异常:

1 import java.util.List; 2 import java.util.ArrayList; 3 4 public class ListErr{ 5 public static void main(String[] args){ 6 //创建一个只想保存字符串的List集合 7 List strList = new ArrayList(); 8 strList.add("疯狂Java讲义"); 9 strList.add("疯狂Android讲义"); 10 //"不小心"把一个Integer对象"丢进"了集合 11 strList.add(5); 12 strList.forEach(str -> System.out.println(((String) str).length())); 13 } 14 } View Code

  使用泛型

    从Java5后,Java引入了”参数化类型“(parameterized type)”概念,允许程序在创建集合时指定集合元素的类型。Java的参数化类型被称为泛型(Generic)

1 import java.util.List; 2 import java.util.ArrayList; 3 4 public class GenericList{ 5 public static void main(String[] args){ 6 //创建一个只想保存字符串的List集合 7 List<String> strList = new ArrayList<String>(); 8 strList.add("疯狂Java讲义"); 9 strList.add("疯狂Android讲义"); 10 //"不小心"把一个Integer对象"丢进"了集合 11 strList.add(5); 12 strList.forEach(str -> System.out.println(((String) str).length())); 13 } 14 } View Code

  Java7泛型的“菱形”语法:

    在Java7以前,若使用带泛型的接口、类定义变量,那么调用构造器创建对象时构造器后面也必须带泛型,这就显得有些多余:

    List<String> strList = new ArrayList<String>();

    Map<String, Integer> scores = new HashMap<String, Integer>();

  Java8之后,可以这样写:

    List<String> strList = new ArrayList<>();

    Map<String, Integer> scores = new HashMap<>();

    把两个尖括号并排放在一起非常像一个菱形,这种语法也被称为“菱形”语法。

1 import java.util.List; 2 import java.util.ArrayList; 3 import java.util.Map; 4 import java.util.HashMap; 5 6 7 public class DiamondTest{ 8 public static void main(String[] args){ 9 //Java 自动推断出ArrayList的<>里应该是String 10 List<String> books = new ArrayList<>(); 11 books.add("疯狂Java讲义"); 12 books.add("疯狂Android讲义"); 13 //遍历books集合,集合元素就是String类型 14 books.forEach(ele -> System.out.println(ele.length())); 15 //Java自动推断出HashMap的<>里应该是String,List<String> 16 Map<String, List<String>> schoolsInfo = new HashMap<>(); 17 //Java自动推断出ArrayList的<>里应该是String 18 List<String> schools = new ArrayList<>(); 19 schools.add("斜月三星洞"); 20 schools.add("西天取经路"); 21 schoolsInfo.put("孙悟空", schools); 22 //遍历Map时,Map的key是String类型,value是List<String>类型 23 schoolsInfo.forEach((key, value) -> System.out.println(key + "-->" + value)); 24 } 25 } View Code

深入泛型:

  定义泛型接口、类:

    泛型就是允许在定义类、接口、方法时使用类型形参,这个类型形参将在声明变量、创建对象、调用方法时动态地指定(即传入实际的类型参数,也可称为类型实参)。

    可以为任何类、接口增加泛型声明(并不是只有集合类才可以使用泛型声明,虽然集合类是泛型的重要使用场所)。

1 //定义Apple类时使用了泛型声明 2 public class Apple<T>{ 3 //使用T类型形参定义实例变量 4 private T info; 5 public Apple(){} 6 //下面方法中使用T类型形参来定义构造器 7 public Apple(T info){ 8 this.info = info; 9 } 10 public void setInfo(T info){ 11 this.info = info; 12 } 13 public T getInfo(){ 14 return this.info; 15 } 16 public static void main(String[] args){ 17 //由于传给T形参的是String,所以构造器参数只能是String 18 Apple<String> a1 = new Apple<>("苹果"); 19 System.out.println(a1.getInfo()); 20 //由于传给T形参的是Double,所以构造器参数只能是Double或double 21 Apple<Double> a2 = new Apple<>(5.67); 22 System.out.println(a2.getInfo()); 23 } 24 } View Code

     当创建带泛型声明的自定义类,为该类定义构造器时,构造器名还是原来的类名,不要增加泛型声明。如:为Apple<T>类定义构造器,其构造器名依然是Apple,而不

     是Apple<T>!调用该构造器是却可以使用Apple<T>的形式,应该为T形参传入实际的类型参数。

  从泛型类派生子类:

    创建带泛型声明的接口、父类后,可以为该接口创建实现类或派生子类。需要注意的是:当使用这些接口、父类是不能再包含类型形参<T>:

      //定义类A继承Apple类,Apple类不能跟类型形参

      public class A extends Apple<T>{ }//这是错误的

    定义方法时,方法中的形参数据,被称为形参或数据形参。在使用方法时,必须为这些形参传入实际的数据。

    类型形参也一样,在定义类、接口、方法时可以声明类型形参如:<T>,但使用这些类、接口、方法时应该为该类型形参传入实际的类型,如:<String>。

      //使用Apple类时,为T形参传入String类型

      public class A extends Apple<String>{ }

    也可以不为类型形参传入实际的类型:

      //使用Apple类时,没有为T形参传入实际的类型参数

      public class A extends Apple{ }

    若从Apple<String>类派生子类,则在Apple类中所有使用T类型形参的地方都将被替换成String类型,那么它的子类将会继承到String getInfo()和void setInfo(String info)两

 

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

网友点评
d