泛型概述
- 数组与集合
java中可以定义任意类型的属性,例如String[]中存放的就是Stirng类型,泛型允许Java创建持有任意类型的集合对象。如new ArrayList()表示这个ArrayList只能有string类型对象。 - 类型变量
具有一个或多个类型参数的类就是泛型类。泛型类至少有一个类型变量,需要在创建的时候为它赋值,必须是相同类型。ArrayListarr = new ArrayList();其中,string就是给arrayList类的类型变量赋值。如:boolean add(E e);其中,e的类型就是变量,会被string替换。变为Boolean add(string e). - 泛型的好处
泛型把只能在运行期才能找到的错误推到了编译期。
定义泛型类
自定义泛型类语法
public class A{}
定义泛型时,需要在类名后面给出一对尖括号,尖括号中给出1-n个类型变量在泛型中使用类型变量
用户在使用泛型类时,需要为类型变量赋值。类如new A().
在泛型类中可以使用类型变量:
public class A<T>{
private T t;
public A(T t){
this.t = t;
}
public T get(){
return t;
}
}
当用户创建A类对象时,就会给A类的类型变量T赋值。如new A(),这说明A类中所有的T都会被string替换。
public class A<T>{
private string t;
public A(string t){
this.t = t;
}
public string get(){
return t;
}
}
- 类型变量的限制
static方法中不能使用类型变量T,定义了T类型的变量,但是t的类型无法确定。
泛型方法
泛型类说明这个类有类型变量,在创建这个类对象时需要给类型变量赋值。泛型方法是说明这个方法有类型变量,在调用这个方法的时候需要给类型变量赋值。
public <T>T get(T[]ts,int index){
return ts[index];
}
注意,在返回值前面定义类型变量。
get()方法是一个泛型方法,他有一个类型变量T,这说明在调用get方法的时候需要给get方法的T赋值。
如果要定义有意义的泛型方法需要:
1.参数需要使用类型变量
2.返回值需要使用类型变量
所有通常在调用泛型方法时,只需要传递参数就可以了。
String[] str;
string s = o.get(str,0);
上面代码中给get方法的类型变量赋值string,因为传递参数是string。
泛型边界
编译期状态,例如内部类,只有编译器知道,jvm不认识。
- jvm不知道什么是泛型。都是编译器强制转换的结果。编译器只认识普通的类。
通配符的作用
Object[] objs = new String[10];
objs[0] = new Integer(100);
上面代码编译是可以通过的,但在运行时会出现ArrayStoreException。因为objs数组真实的身份是String[],向String[]数组中存放Integer对象当然是不行的。
ArrayList list = new ArrayList();
list.add(new Integer(100);
上面代码在第一行位置编译失败,因为泛型根本就不让把ArrayList赋值给ArrayList,对于ArrayList而言,只能赋值ArrayList,其他的什么都不能赋值。
这也说明一个问题:
public static void printList(List list) {…}
调用printList()方法只能传递给它List类型的参数,而不能传递List,或者List,这说明我们的printList()方法有很多的限制,不够通用!!!你可能会想我再重载几次printList()方法吧,但这是行不通的!
public static void printList(List list) {…}
public static void printList(List list) {…}
因为JVM不知道什么是泛型,这两个方法在到了JVM那里时都是会把泛型参数擦除,这两个方法就是相同的方法了,擦除之后即:
public static void printList(List list) {…}
public static void printList(List list) {…}
当然JVM不可能看到这样的代码,因为编译器不能让你编译通过!
处理这个问题需要使用通配符!
2 子类型通配符
public static void printList(List
增强for
- 增强for概念
- 可以循环遍历数组或集合
- 增强for循环的格式
- for(元素类型 e:数组或集合对象)
- 增强for优缺点
- 只能从头到尾遍历全部,不能部分遍历
- 在遍历是不能获取当前下标
- 使用简单
- 比迭代器方便
- 增强for与Iterable接口
- 任何实现了iterable接口的类都可以使用增强for