泛型:通过给javac编译器使用的,可以限制集合中的输入类型,让编译器挡住原程序
中的非法输入,编译器编译带类型说明的集合时会去掉类型信息,使程序运行效率不受影
响、对于参数化的泛型类型,getClass方法的返回值和原始类型相同。由于编译生成的字
节码会去掉泛型的类型信息,只要跳过编译器,就可以往某个泛型集合中加入其它类型的
数据。
泛型中的术语1、ArrayList<E>的E成为类型变量或类型参数
2、整个ArrayList<Integer>成为参数化的类型
3、ArrayList<Integer>中的Integer成为类型参数的实例或实际类型参数
4、ArrayList成为原始类型
具体泛型的用例
public static void main(String[] argc) {
Child c1 = new Child(4, 5);
Child c2 = new Child(9, 2);
Child c3 = new Child(5, 4);
//泛型常用
Map<Integer, Child> map = new HashMap<Integer, Child>();
map.put(1, c1);
map.put(2, c2);
map.put(4, c3);
//用Iterator遍历
for(Iterator i=map.entrySet().iterator(); i.hasNext(); ) {
Map.Entry<Integer, Child> m = (Map.Entry<Integer, Child>)i.next();
System.out.println(m.getKey() + " --- " + m.getValue().getM());
}
}
domain类
package com.heima.on;
public class Children {
private int x;
private int y;
public Children(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Children other = (Children) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
根据调用泛型方法时实际传递的参数类型或返回值的类型来推断,具体规则如下,
1、当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处
的实际应用类型来确定,这很容易凭感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定
泛型参数的类型 如
swap(new String[3](3, 4)) ->static <E> void swap(E[] a, int i, int j)
2、当某个类型变量在整个参数列表中的所有参数和返回值总的多处被应用了,如果调用方法时这多处的实际
应用类型都对应同一种类型来确定,这个很容易凭感觉推断出来,如
add(3,4)->static <T> T add(T a, T b)
3、当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时多处的实际应用
类型对应到了不同的类型,且没有使用返回值,这时候取多个参数中的最大交集,如何,下面语句实际对应的
类型就是Number了,编译没有问题,只是运行时出问题:
fill(new Integer[3], 3.5f) ->static <T> void fill(T[] a, T v)
4、当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际
应用类型对应到了不同的类型,并且使用返回值,这时候优先考虑返回值的类型,如,下面语句实际对应的类型
就是Integer了,编译将报告错误,将变量的类型改为float,对比eclipse报告的错误提示,接着在将变量x的类型
改为Number, 则没有了错误:int x=(3, 3.5f) -> static <T> T add(T a, T)
5、参数类型的类型推断具有传递性,下面第一种情况推断实际参数类型为Object,编译没有问题,而第二种情况
则根据参数化的Vector类实例将类型变量直接确定为Sting类型,编译将出现问题:
copy(new Integer[5], new String[5]) -> static <T> void copy(T[] a, T[] b);