1、概述
(1) 泛型的引入
早期使用 Object 类型接收任意的对象类型,但是在实际使用中,会有类型转换问题,存在安全隐患,于是在 JDK5 后引入泛型来解决这个安全问题。
class Person
{
private String name;
private int age;
public Person()
{
}
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
public void introduce()
{
System.out.println("我叫" + name + ",今年" + age + "岁");
}
}
如上代码所示,ArrayList 是一个存储 Object 类型元素的集合,add(Object o) 方法添加元素,因为要调用 Person 类特有的 introduce() 方法,所以在遍历集合时需要将元素向下转型为 Person类型。但是集合中混入了一个 String 类型的 "zhaoLiu",无法将其转换为 Person 类型,有类型转换问题,存在安全隐患,所以引入泛型。
(2) 泛型的概念
泛型是一种把类型明确的工作推迟到创建对象或者调用方法的时候的特殊类型,参数化类型,把类型当作参数一样传递。
(3) 泛型格式和用法
(一) 泛型类(接口)
public class ArrayList<E>
{
public boolean add(E e)
{
相关代码
}
public E get(int index)
{
相关代码
}
}
其中的 <E> 就是泛型,E 必须是引用数据类型,有了泛型,上面集合存储元素的代码变成如下:
此时 list 中只能添加 Person 类型,list.add("zhaoLiu") 自动报错,并且在获取元素的时候不需要再转型,黄色警告线也消失了。
(二) 泛型方法
泛型方法由分为声明类时传入泛型和声明方法时传入泛型,前者如 (一) 中的泛型类 ArrayList<E> 中的 add(E e) 和 E get(int index) 所示,声明方法时传入泛型如下所示
public class GenericFunDemo
{
public static void main(String[] args)
{
String[] str = {"java", "HTML", "Android"};
int[] nums = {5, 20, 13, 14};
System.out.println(arrayToString(str));
System.out.println(arrayToString(nums));
}
public static <T> String arrayToString(T[] tArray)
{
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i = 0; i < t.length; i++)
{
sb.append(tArray[i]);
if(i == t.length - 1)
{
sb.append("]");
break;
}
sb.append(", ");
}
return sb.toString();
}
}
泛型方法的声明格式:权限修饰符 <T> 返回值类型 方法名(参数列表)
(二) 泛型的好处
把运行时期的问题提前到了编译期间
避免了强制类型转换
优化了程序设计,解决了黄色警告线
2、高级
(一) 通配符
用 "?" 表示任意数据类型
public class GenericDemo
{
public static void main(String[] args)
{
ArrayList<?> strList = new ArrayList<String>();
ArrayList<?> intList = new ArrayList<Integer>();
}
}
(二) 向上限定
? super E:? 为 E 的父类或者其本身
public class GenericDemo
{
public static void main(String[] args)
{
ArrayList<? super Dog> animalList = new ArrayList<Animal>();
ArrayList<? super Dog> animalList = new ArrayList<Dog>();
}
}
class Animal
{
}
class Dog extends Animal
{
}
(三) 向下限定
? extends E:? 为 E 的子类或者其本身
public class GenericDemo
{
public static void main(String[] args)
{
ArrayList<? extends Animal> animalList = new ArrayList<Animal>();
ArrayList<? extends Animal> animalList = new ArrayList<Dog>();
}
}
class Animal
{
}
class Dog extends Animal
{
}