前言
泛型在代码之初就一直在使用,而且使用的时候一直和集合一起用,对他的理解非常片面,只知道它对编译时集合元素的类型进行检查,但是对于为什么这么使用,以及什么情况下可以使用泛型却不是很清楚!
内容
1.什么是泛型?
泛型就是允许在定义类,接口,方法时使用类型形参,这个类型形参将在声明变量,创建对象,调用方法时动态的指定(即传入实际的类型参数,类型实参)。注:可以为任何类,接口增加泛型声明,并不是只有集合类才可以使用泛型声明,虽然集合类是泛型类的重要场所。
2.泛型的特点
/**
*当创建带有泛型声明的java类,为该类定义构造器的时候,构造器还是原来的类型,不是Apple<T> ,不过要增加泛型声明。
*/
public class Apple<T> {
private T info; //运用T类型形参定义实例变量
public Apple(){}
public Apple(T info){
this.info=info; //使用他T类型形参定义构造器
}
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
public static void main(String[] args) {
Apple<String> a1=new Apple<>("苹果");// JAVA7开始,java可以推断尖括号后面是什么类型
Apple<Double> a2=new Apple<>(5.67);
// 虽然Apple<String>类像特殊的Apple类,该Apple<String>对象只能添加String对象为集合元素,
//但是实际上,系统并没有为Apple<String>生成class文件,也不会把它当做新的类来处理
System.out.println(a1.getClass()==a2.getClass());//返回结果为true
System.out.println(a1.getInfo());
}
}
- 不管为泛型的类型形参传入什么类型实参,对于java来说,它们依然被当成同一类来处理,在内存中也只占用一块内存空间。在静态方法,静态初始化块或者静态变量的声明和初始化不允许使用泛型形参。
- 系统不会生成真正的泛型类,所以instanceof运算符之后不能使用泛型类。
- 从泛型类派生子类,不能使用类型形参,必须制定类型实参。
- 数组和泛型有所不同,数组支持形变,而list不支持形变。
3.类型通配符&类型形参
?作为一个类型实参传给List集合,List<?>
代表了元素位置类型List,?被称为通配符,它的元素类型可以匹配任何类型。注:带有通配符的list表示各种list的父类,可以访问,并不能添加元素到其中。
总结
并不是集合可以用泛型,现在定义的所有类都可以为泛型,但是泛型的使用中我们要注意,它不支持形变继承