1.为什么需要泛型?
JDK提供了ArrayList,可以看作“可变长度”的数组:
- 比数组使用方便
示例1:如果使用ArrayList存储String类型: - 需要强制转型
- 不方便,易出错
//演示代码
public class ArrayList1{
private Object[] array;
public void add(Object e){...}
public void remove(int index){...}
public Object get(int index){...}
}
public class Main {
public static void main(String[] args){
ArrayList1 list = new ArrayList1();
list.add("hello");
String one = (String) list.get(0);//需要强制转型
list.add(new Integer(123));//加入Integer类型,提示Error : ClassCastException
String second = (String) list.get(1);
}
}
示例2: 为了解决示例1中的问题,为String单独编写一种ArrayList:
- 不需要强制转型
- 编译器强制检查放入的类型
public class ArrayList1{
private String[] array;
public void add(String e){}
public void remove(int index){}
public String get(int index){return array[index];}
}
public class Main {
public static void main(String[] args){
ArrayList1 list = new ArrayList1();
list.add("hello");
String one = list.get(0);//不再需要强制转型
list.add(new Integer(123));//IDE就会提示编译错误,不需要等到编译时
String second = (String) list.get(1);
}
}
新的问题:还需要为其他所有从class单独编写一种ArrayList:Long, Double, Person, Integer。
必须把ArrayList变成一种模版.
1.1范型就是定义一种模版,例如ArrayList
- 在代码中为用到的类创建对应的ArrayList
* ArrayList strList = new ArrayList(); - 编译器针对类型做检查
* strList.add("hello");
* strList.add(new Integer(123));//compile error
public class ArrayList1<T> {
private T[] array;
public void add(T e){}
public void remove(int index){}
public T get(int index){return array[index];}
}
public class Main {
public static void main(String[] args){
ArrayList1<String> strList = new ArrayList1<String>();
ArrayList1<Integer> inList = new ArrayList1<Integer>();
ArrayList1<Float> flList = new ArrayList1<Float>();
}
}
2.泛型的继承关系
ArrayList1<T>实现了List<T>接口,ArrayList1<T>可以向上转型为List<T>.
//示例代码,忽略错误
public class ArrayList1<T> implements List<T> {
private T[] array;
public void add(T e){}
public void remove(int index){}
public T get(int index){return array[index];}
//List<T>的方法...
}
public class Main {
public static void main(String[] args){
ArrayList1<String> strList = new ArrayList1<String>();
List<String> list = new ArrayList<String>();
}
}
不能把ArrayList1<Integer>向上转型为ArrayList1<Numberr>或List<Number>
ArrayList1<Integer>和ArrayList1<Number>两者没有继承关系。
而Number包含float的子类,ArrayList1<Integer>不接受float。
import java.util.ArrayList;
//使用JDK的ArrayList<t>
public class Main {
public static void main(String[] args){
ArrayList<String> strList = new ArrayList<String>();
strList.add("abc");
strList.add("xyz");
//strList.add(new Integer(123));
String first = strList.get(0);
System.out.println(first);
}
}
3.总结:
- 泛型就是编写模版代码来适应任意类型
- 不必对类型进行强制转换
- 编译器将对类型进行检查
- 注意泛型的继承关系:
* 可以把ArrayList<Integer>向上转型为List<Integer> (T不能变)
* 不能ArrayList<Integer>向上转型为ArrayList<Number>