这样做带来例如以下两个问题:
1:集合对元素的类型没有限制这可能会依法异常
2:因为把对象放进去的时候没有考虑类型可是取出来的时候是Object类型那么问题来了
假设想要转换成放进去之前的元素类型那么就要进行强制类型转换添加了编程的复杂度
并且还可能引发ClassCaxtException。
以下介绍编译的时候不检查类型可能引发的异常:
public class ListErr
{
public static void main(String[] args)
{
//创建一个仅仅想保留字符串的List结婚
List strList = new ArrayList();
strList.add("疯狂java讲义");
strList.add("疯狂android讲义");
//一不小心将Integer对像放进了集合中
atrList.add(5);
//以下的语句将会出现错误
strList.forEach(str->System.out.println(((String)str).length()));
}
}
使用泛型
从java5以后。java引入了"參数化类型"的概念。同意程序在创建集合时指定结合元素的类型,參数化类型被称作泛型。
使用泛型改动之前的程序:
public class ListErr
{
public static void main(String[] args)
{
//创建一个仅仅想保留字符串的List结婚
List<String> strList = new ArrayList<String>();
strList.add("疯狂java讲义");
strList.add("疯狂android讲义");
//一不小心将Integer对像放进了集合中
//这种话这个就会在编译的时候出现错误。
atrList.add(5);
//本句话中将不会出现错误并且不须要进行强制类型转换
strList.forEach(str->System.out.println(str.length()));
}
}
在集合接口、类后添加尖括号尖括号里添加数据类型表名它仅仅能保存特定类型的对像上面的代码不仅更加健壮并且程序
更加的简洁集合自己主动记住全部元素的数据类型无需对集合元素进行强制类型转换。
java 7 反省的“菱形”语法
java7曾经,假设使用了带泛型的接口,类定义变量,那么吊哟偶个构造器创建对像构造器的后面也必须带泛型。这显得有些多余了
比如:List<String> StrList = new ArrayList<String>();
上面语句是多余的可是在java7之前是必需要写的可是经过jjava7的改进之后仅仅需要使用菱形语法这种话就能大大缩短时间
java能够自己主动的推断类型比如:
比如:List<String> StrList = new ArrayList<>();仅仅须要写上<>不再须要写上完整的类型即可了
//须要注意的是java斑病应该在1.8才干编译以下的程序!
import java.util.*;
public class DiamondTest
{
public static void main(String[] args)
{
// Java自己主动判断出ArrayList的<>里应该是String
List<String> books = new ArrayList<>();
books.add("我是李刚");
books.add("我不是李刚");
// 遍历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("西天取经路");
schoolsInfo.put("孙悟空" , schools);
// 遍历Map时,Map的key是String类型,value是List<String>类型
schoolsInfo.forEach((key , value) -> System.out.println(key + "-->" + value));
}
}
深入泛型
所谓泛型就是定义类、接口、方法时使用类型形參,这个类型形參将在声明变量、创建对像、调用方法时动态的指定
泛型同意在定义接口、类时声明类型形參除此之外我们见到的Iterator<E> Map<E> 这表明它们是一种特殊形式的数据
类型是一种和set不同的数据类型能够觉得是其子类
须要注意的是:
包括泛型声明的类型能够在定义变量、创建兑现时传入一个类型实參,从而能够动态地生成无数朵花和逻辑上的子类,
可是这样的子类在物理上是不存在的
创建出于自己的带反省声明的类
// 定义Apple类时使用了泛型声明
public class Apple<T>
{
// 使用T类型形參定义实例变量
private T info;
public Apple(){}
// 以下方法中使用T类型形參来定义构造器
public Apple(T info)
{
this.info = info;
}
public void setInfo(T info)
{
this.info = info;
}
public T getInfo()
{
return this.info;
}
public static void main(String[] args)
{
// 因为传给T形參的是String,所以构造器參数仅仅能是String
Apple<String> a1 = new Apple<>("苹果");
System.out.println(a1.getInfo());
// 因为传给T形參的是Double,所以构造器參数仅仅能是Double或double
Apple<Double> a2 = new Apple<>(5.67);
System.out.println(a2.getInfo());
}
}
这样我们在使用Apple<T>时候就能够为形參传入实际类型须要注意的是为类定义构造器
的时候构造器的名称还是类名不要添加反省声明比如Apple<T>的构造器就是Apple不是Apple<T>
此外还能够派生子类、定义泛型方法、使用通配符、泛型和泛型数组、通配符的上限和下限假设
想深入学习的话请自行查阅
原文:http://www.cnblogs.com/gcczhongduan/p/5095271.html