知识点:
1.泛型的出现
2.泛型基础(泛型方法,泛型类,泛型接口,无限制通配符类型,擦除)
3.Set<Object>, Set<?>, Set, Set<T>的区别
在学习泛型这一章之前,我们应该先了解一下泛型基础。可以帮助大家理解这一章节的内容。
1.泛型的出现
泛型指的是参数化类型。什么叫参数化类型,我们来简单的看一下,看下面代码,两个方法,第一个方法只有a是形参,第二个方法类型和a都是形参。T可以是任意类型,String,Integer所有对象类型都可以作为参数传递进来。这就是参数化类型。
public void put(String a) {} 参数a类型为字符串
public void put(T a){} 参数a类型为T
泛型的好处
a.安全性,可读性。
看下面代码,我们可以放任何对象到列表a中,但当我们取出对象的时候,需要做强制类型转换,如果一个类型转换出错,程序就会异常,关键是这种异常在编译期间我们居然发现不了。再看列表b,优先我们一看就知道列表b只能放String类型,当我们存其他类型的时候,编译期间就可以发现错误。
List a = new ArrayList();
List<String> b = new ArrayList<String>();
泛型的出现,让代码变得更加灵活,代码的功能性更加强大。我们看一个简单的例子,下面是两个存放一个值的功能类,我们可以把一个值存放在HolderA和HolderB中。HolderA只能存放String类型,但是HolderB却可以存放任意类。泛型的灵活性远远不止这些。
public class HolderA {
private String value;
public String getValue() {
return name;
}
public void setValue(String value) {
this.value= value;
}
public HolderA (String value) {
this.value= value;
}
}
public class HolderB {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public HolderB (T value) {
this.value = value;
}
}
2.泛型基础(泛型方法,泛型类,泛型接口,无限制通配符类型,擦除)
a.泛型类,泛型方法。下面一个简单哦泛型类和泛型方法,T可以是任何类型。
class Box<T> { 泛型类
private T data;
public Box() {
}
public Box(T data) { 泛型方法
this.data = data;
}
public T getData() {
return data;
}
}
public interfaceList<E>
{
void add(E x);
Iterator<E> iterator();
}
c.无限制通配符类型。看下面代码,我们需要方法getData能够支持三中类型,String,Integer,Number。但是如果没有无限制通配符?,我们只能指定一个类型。?表示支持任意类型。这里的?是实参,和String,Interger,Number都是实参,这三种是已知类型,?表示的是任意类型。
public class GenericTest {
public static void main(String[] args) {
Box<String> name = new Box<String>("corn");
Box<Integer> age = new Box<Integer>(712);
Box<Number> number = new Box<Number>(314);
getData(name);
getData(age);
getData(number);
}
public static void getData(Box<?> data) { ?就是无限制通配符
System.out.println("data :" + data.getData());
}
}
d.擦除
ArrayList<String>, ArrayList<Integer>看起来是不同类型,其实是同一种类型,都是ArrayList。在编译期间会去掉任何具体的类型参数的信息,在运行的时候String,Integer其实都是当作Object来处理的。
擦除的好处:我们可以同时使用泛化和非泛化的类型,保证了向下兼容性。以前的非泛型的代码也可以使用。
3.Set<Object>, Set<?>, Set, Set<T> 的区别
首先像T,K,V等是用来表示泛型的形参的。用来定义泛型方法,泛型类的时候用到的。他和Object,?有本质的区别。Object和?都是表示用户想要传入的类型,是实参。
Set<Object> 表示对象的集合,集合中存放对象。
Set<?> 表示任意类型的集合,集合中可以存放任意类型
Set 是一个原生态类型,和泛型无关
Set<T> 表示一个T的集合,其中的T是形参,等待传入像Integer,String,甚至是?的实参。
关于Set<T>,Set<?>多少两句,从使用上来区别更容易理解:
a.类型参数<T>主要用于声明泛型类或泛型方法
b.无界通配符<?>主要用于使用泛型类或泛型方法
有了上面泛型的基础知识后,我们后面再来学习Effective Java关于泛型的系列文章。