一 Java集合设计的两个问题
1 集合对元素类型没有任何限制,这样可能引发一些问题:例如想创建一个只能保存Dog对象的集合,但程序也可以轻易地将Cat对象“丢”进去,所以可能引发异常。
2 由于把对象“丢进”集合时,集合丢失了对象的状态信息,集合只知道它盛装的是Object,因此取出集合元素后通常还需要进行强制类型转换。这种强制类型转换既会增加编程的复杂度、也可能引发ClassCastException。
二 编译时不检查异常类型
1 代码示例
import java.util.*;
public class ListErr
{
public static void main(String[] args)
{
// 创建一个只想保存字符串的List集合
List strList = new ArrayList();
strList.add("Java");
strList.add("Android");
// "不小心"把一个Integer对象"丢进"了集合
strList.add(5); // ①
strList.forEach(str -> System.out.println(((String)str).length())); // ②
}
}
2 运行结果
4
7
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at ListErr.lambda$main$0(ListErr.java:14)
at java.util.ArrayList.forEach(Unknown Source)
at ListErr.main(ListErr.java:14)
3 代码分析
程序创建了一个List集合,而且只希望该List集合保存字符串对象,但程序不能进行任何限制,如果在①处不小心把一个Interger对象“丢进了集合”,这将导致程序在②处引发ClassCastException异常,因为程序试图把一个Interger对象转换为String类型。
三泛型的引入
1 泛型介绍
从Java 5以后,Java引入了“参数化类型”的概念,允许程序在创建集合时指定集合元素的类型。列如:List<String>,这表明该List只能保存字符串类型的对象。Java的参数化类型被称为泛型(Generic)。
2 代码示例
import java.util.ArrayList;
import java.util.List;
public class GenericList
{
public static void main(String[] args)
{
// 创建一个只想保存字符串的List集合
List<String> strList = new ArrayList<String>(); // ①
strList.add("Java");
strList.add("Android");
// 下面代码将引起编译错误
strList.add(5); // ②
strList.forEach(str -> System.out.println(str.length())); // ③
}
}
3 运行结果
E:testJavaJava8fanxingsrc>javac GenericList.java
GenericList.java:14: 错误: 对于add(int), 找不到合适的方法
strList.add(5); // ②
^
方法 Collection.add(String)不适用
(参数不匹配; int无法转换为String)
方法 List.add(String)不适用
(参数不匹配; int无法转换为String)
注: 某些消息已经过简化; 请使用 -Xdiags:verbose 重新编译以获得完整输出
1 个错误
4 代码分析
在集合中使用泛型后带来如下优势:
- 程序再也不能“不小心”把其他对象“丢进”strList集合中,在编译的时候就能够发现问题了。
- 程序更加简洁,集合自动记住所有集合元素的数据类型,从而无需对集合元素进行强制类型转换。
四 Java 7 泛型的菱形语法
1 菱形介绍
在Java 7以前,如果使用带泛型的接口、类定义变量,那么调用构造器创建对象时,构造器的后面也必须带泛型,这显得多余。例如如下这条语句。
List<String> strList = new ArrayList<String>();
上面这条语句中粗体代码部分完全多余,但再Java 7以前这是必须的,不能省略。从Java 7开始,Java允许在构造器后不带需要带完整的泛型信息,只要一对(<>)即可,Java可以推断尖括号应该是什么泛型信息。即上面的语句可以改写成如下形式:
List<String> strList = new ArrayList<>();
两个尖括号并排在一起非常像一个菱形,这种语法也被称为“菱形”语法。下面程序示范了Java 7的菱形语法。
2 代码示例
import java.util.*;
public class DiamondTest
{
public static void main(String[] args)
{
// Java自动推断出ArrayList的<>里应该是String
List<String> books = new ArrayList<>();
books.add("Java");
books.add("Android");
// 遍历books集合,集合元素就是String类型
books.forEach(ele -> System.out.println(ele.length()));
// Java自动推断出HashMap的<>里应该是String , List<String>
Map<String , List<String>> schoolsInfo = new HashMap<>();
// Java自动推断出ArrayList的<>里应该是String
List<String> schools = new ArrayList<>();
schools.add("床前明月光");
schools.add("疑是地上霜");
schools.add("举头望明月");
schools.add("低头思故乡");
schoolsInfo.put("李白" , schools);
// 遍历Map时,Map的key是String类型,value是List<String>类型
schoolsInfo.forEach((key , value) -> System.out.println(key + "-->" + value));
}
}
3 运行结果
E:testJavaJava8fanxingsrc>java DiamondTest
4
7
李白-->[床前明月光, 疑是地上霜, 举头望明月, 低头思故乡]
4 代码分析
上面的程序有3行就是“菱形”语法的示例。从该程序不难看出,“菱形”语法对原有的泛型并没有改变,只是更好地简化了泛型编程。
最后
以上就是可靠花瓣最近收集整理的关于泛型的引入的全部内容,更多相关泛型内容请搜索靠谱客的其他文章。
发表评论 取消回复