java集合有一个缺点:把对象丢进集合里之后,集合就会忘记这个对象的数据类型。因为需要有很好的通用性,不可能把类型写死的。
一 使用泛型
List<String>lists=new List<String>();
二 定义泛型接口,类
1 接口
public interface List<E>{
void add(E x);
Iterator <E> iterator;
}
//等同于List<String>
public interface ListString extends List{
void add(String x)
}
2 类
public class Apple<T>{
private T info;
public Apple(){}
public Apple(T info){
this.info=info;
}
public void setInfo(T info){
this.info=info;
}
public void getInfo(T info){
return this.info;
}
}
Apple<String> a1=new Apple<>("苹果")
a1.getInfo();//打印苹果
Apple<Double> a2=new Apple<>(6.66);
3 泛型类派生子类
public class A extends Apple<E >{}//Apple不能用类型形参
public class A extends Apple<String>{//可以
public String getInfo(){
return "子类"+super.getInfo();
}
//返回类型不一致,错误的
public Object getInfo(){
return "子类";
}
4 并不存在泛型类
List<String>a =new ArrayList<>();
List<String> b=new ArrayList<>()
a.getClass()==b.getClass();//true 不管泛型的实际类型参数是什么,它们运行总有同样的类
5 静态方法,静态初始化块,静态变量不能使用类型形参
stitac T info;//错误
public static void bar(T mag){//错误
}
* if (a instanceof ArrayList<String>())//instanceof 运算符后不能使用泛型类
*public void test (List<Object>c){
for(int i=0;i<c.size();i++){
c.get(i);
}
}
List<String> strList=new ArrayList<>();
strList.test();//错误 即List<String>并不是List<Object>的子类
*List<Integer> a=new ArrayList<>();
List<Number> b=a;//错误
二 使用类型通配符
public void test(List<?>c){
for(int i=0;i<c.size();i++){
c.get(i);
}
}
List<?> c=new ArrayList<String>();
c.add(new Object());//错误,无法确认c集合元素的类型,所以不能添加元素。null例外
1 设定类型通配符的上限
public abstract class Shape{
public abstract void draw(Canvas c);
}
public class Circle extends Shape{
public void draw(Canva c){
System.out.println("在画布"+c+“上画一个园”)
}
public class Rectangle extends Shape{
public void draw(Canva c){
System.out.println("在画布"+c+“上画一个矩形”)
}
public class Canvas{
public void drawAll(List<Shape>shape){
for(Shape s:shapes){
s.draw(this);
public void drawAll(List<? extends Shape>shape){
for(Shape s:shapes){
s.draw(this);
}
List<Circle> a=new ArrayList<>();
Canvas c=new Canvas();
c.drawAll(a);
List<Circle>不是List<Shapr>的子类 ,改为红色部分就可以了。但是不能把子类加进去 shapes.add(0,Rectangle());
}
}
}
2 设定类型形参的上限
public class Apple<T exends Number>{
}
Apple<Integer >as=new Apple<>();//符合
Apple<String >as=new Apple<>();//错误
三定义泛型方法
static <T>void formArrayToCollection(T[]a,Collection<T>c){
for(T o:a){
c.add(o);
}
}
Object[] ca=new Object[100];
Collection<Object>co=new ArrayList<>();
fromArrayToCollection(ca,co);
//static <T> void test(Collection<T>from,Collection<T>to){//编译器无法准确判断出类型形参的类型
static <T>void test(Collection<? extends T>from,Collection<T>to){
for(T ele :from){
to.add
}
}
public static <T>void copy(List<T> dest,List <? extends T>){}//List的copy方法
四 泛型结构器
class Foo{
public <T>Foo(T t){
System.out.println(t);
}
}
new Foo("aaa");
new Foo(123);
public static <T>T copy(Collection<? super T >dest,Collection<T>src){
T last=null;
fot (T ele:src){
last=ele;
dest.add(else);
}
}
五 泛型不支持数组