1.泛型
ArrayList<Dog> arrayList = new ArrayList<Dog>();
//1.当我们ArrayList<Dog>表示存放到ArrayList集合中的元素是Dog类
//2.如果编译器发现添加的类型,不满足要求,就会报错
//3.在便利的时候,可以直接取出Dog类型而不是Object
arrayList.add(new Dog("旺财",10));
arrayList.add(new Dog("小法",1));
for(Dog dog : arrayList) {
System.out.println(dog.name +" " + dog.age);
}
*泛型的好处
1.编译时,检查添加元素的类型,提高了安全性
2.减少了类型转换的次数,提高了效率
1.泛型介绍
*泛型(广泛的类型) --> Integer,String,Dog
public class ArrayList{} //E成为泛型
1.泛型又称参数化类型,解决数据类型的安全性问题
2.在类声明或实例化时只要指定好需要的具体的类型即可
3.Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常
4.泛型的作用:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型
class Person<E> {
E s;//E表示s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
public Person(E s) {//E也可以是参数类型
this.s = s;
}
public E f() {//返回类型使用E
return s;
}
}
2.泛型的声明
interface 接口{} 和class 类 <T,V>{}
*说明
1.其中,T,K,V不代表值,而是表示类型
2.任意字母都可以,常用T表示,是Type的缩写
*泛型的实例化:
1.List strList = new ArrayList();
2.Iterator iterator = customers.iterator();
//使用泛型方式给HashMap放入学生对象
HashMap<String, Student> hm = new HashMap<String, Student>();
hm.put("tom", new Student("tom",28));
Set<Map.Entry<String, Student>> entries = hm.entrySet();
Iterator<Map.Entry<String,Student>> iterator = entries.iterator();
3.泛型注意细节
1.<>内只能放引用类型Integer之类的,不能是int之类的基本数据类型
2.在给泛型指定具体类型后,可以传入该类型或其子类类型
class A{}
class B extends A{}
class Pig<E> {
E e;
public Pig(E e) {
this.e = e;
}
}
main()
{
Pig<A> aPig = new Pig<A>(new A());
Pig<A> aPig2 = new Pig<A>(new B());
}
3.如果没有指定泛型,默认是Object
ArrayList arrayList = new ArrayList();//等价 ArrayList<Object> arrayList = new ArrayList();
4.自定义泛型
*基本语法
class 类名<T、R...> {//...表示可以有多个泛型
成员
}
1.普通成员可以使用泛型(属性、方法)
2.使用泛型的数组,不能初始化
3.静态方法中不能使用类的泛型
4.泛型类的类型,是在创建对象时确定的
5.未指定泛型,默认为Object
//1.Tiger后面有泛型,所有把Tiger成为自定义泛型类
//2.T、R、M泛型的标识符,一般是单个大写字母
//3.泛型标识符可以有多个
//4.普通成员可以使用泛型(属性、方法)
class Tiger<T、R、M> {
String name;
R r;
M m;
T t;
}
5.自定义泛型接口
*基本语法
interface 接口名<T,R...> {
}
1.接口中,静态成员也不能使用泛型
2.泛型接口的类型,在继承接口或者实现接口时确定
3.没有指定类型,默认为Object
interface IUsb<U,R> {
}
//继承接口时,直接指定泛型接口的类型
interface IA extends IUsb<String,Double> { //String指定给U,Double指定给R
}
//实现接口时,直接指定泛型接口的类型
class BB implements IUsb<Integer,Float> {
}
6.自定义泛型方法
*基本语法
修饰符 <T,R...> 返回类型 方法名(参数列表) {
}
1.泛型方法,可以定义在普通类中,也可以定义在泛型类中
2.当泛型方法被调用时,类型会确定
3.public void eat(E e) {},修饰符后没有<T,R…> eat方法不是泛型方法,而是使用了泛型
class Car {//普通类
public <T,R> void fly(T t,R r) {//泛型方法
}
}
class Fish<T,R> {//泛型类
public <U,M> void eat(U u,M m) {//泛型方法
}
}
main()
{
Car car = new Car();
car.fly("宝马",100);//当调用方法时,传入参数,编译器就会确定类型
}
7.泛型的继承和通配符
1.泛型不具备继承性
List<Object> list = new ArrayList<String>();//不可以这样
2.<?>:支持任意泛型类型
3.<? extends A>:支持A类以及A类的子类,固定了泛型的上限
4.<? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限
main()
{
//List<?> 表示任意的泛型类型都可以接受
public static void printCollection1(List<?> c) {
for(Object object :c) {
System.out.println(object)
}
}
public static void printCollection1(List<? extends AA> c) {
for(Object object :c) {
System.out.println(object)
}
}
public static void printCollection1(List<? super AA> c) {
for(Object object :c) {
System.out.println(object)
}
}
}