泛型的好处:
1、编译时,检查添加元素的类型,提高了安全性
2、减少了类型转换的次数,提高效率
概念:
1、泛型又称参数化类型,解决数据类型的安全性问题
2、在类声明或实例化时只要指定好需要的具体类型即可
3、java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。会使代码更简洁更健壮
4、泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值类型,或者是参数类型
注意事项:
1、E只能是引用类型,不可以是基本数据类型
ArrayList<Integer> integers = new ArrayList<>();//true
ArrayList<int> ints = new ArrayList<int>();//错误
2、在指定泛型具体类型后,可以传入该类型或者其子类类型
public class Study {
@SuppressWarnings({"all"})
public static void main(String[] args) {
ArrayList<A> as = new ArrayList<>();
as.add(new B());
}
}
class A{}
class B extends A{}
3、如果不指定泛型类型,则默认为Object
ArrayList<Object> arrayList = new ArrayList<>();
自定义泛型类:
class 类名<T,R...>{ 成员 }可以有多个泛型
注意事项:
1、普通成员可以使用泛型
2、使用泛型的数组,不能初始化
3、静态方法中不能使用类的泛型
4、泛型类的类型,是在创建对象时确定的(需要指定确定的类型)
5、如果在创建对象时,没有指定类型,默认为Object
class Person<T,E,M>{//Person就称为自定义泛型类
//普通成员可以使用泛型(属性、方法)
T name;
E age;
M sal;
T[] ts=new T[3];//使用泛型的数组,不能初始化(不确定T的类型,就无法在开辟空间)
public Person(T name, E age, M sal) {
this.name = name;
this.age = age;
this.sal = sal;
}
public static say(T name){//静态方法不允许使用泛型
System.out.println(name);
}
}
自定义泛型接口:
interface 接口名<T,R...>{ }
注意事项:
1、接口中,静态成员也不能使用泛型
2、泛型接口的类型,在继承接口或者实现接口时确定
3、没有指定类型,默认为Object
interface Usb<U,R>{
R get(U u);
void say(U u,R r);
}
class A implements Usb<String,Double>{
@Override
public Double get(String s) {
return 1.0;
}
@Override
public void say(String s, Double aDouble) {
System.out.println(s+aDouble);
}
}
自定义泛型方法:
修饰符 <T,R...> 返回类型 方法名(参数列表){}
注意事项:
1、泛型方法,可以定义在普通类中,也可以定义在泛型类中
2、当泛型方法被调用时,类型会确定
3、public void say(E e){}修饰符后没有<T,R..>,此时不是泛型方法,而是使用了泛型
class A{
public <T,R> void say(T t,R r){}//泛型方法
}