泛型
泛型语法
泛型可以在编译的时候检查元素的类型,提高安全型;减少类型转换次数,提高效率
List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog("小黄",1));
dogs.add(new Dog("小花",2));
dogs.add(new Dog("小红",2));
//遍历
for(Dog dog: dogs){
System.out.println(dog.getName() + "," + dog.getAge());
}
- 泛型又称为参数化类型,在JDK5.0中出现,解决数据类型中的安全性问题。
- 在类声明或者实例化的时候指定需要的具体类型即可
- Java泛型保证了在编译时没有发生警告,在运行时就不会发生类型转换异常的错误,同时代码更简洁、健壮
- 泛型的作用:可以在类声明的时候通过一个标识标识类中某个属性的类型,或者某个方法的返回类型或者参数类型。
public class Generic2 {
public static void main(String[] args) {
Person<String> person = new Person<String>("hello");
}
}
//在类定义的时候指定类型
class Person<T>{
//泛型类型的属性
T s;
//用泛型作为参数类型
public Person(T s) {
this.s = s;
}
//返回泛型
public T getS() {
return s;
}
public void setS(T s) {
this.s = s;
}
}
泛型的声明:
interface 接口
class 类<K,V>{}
其中T,K,V不代表值,代表类型
泛型实例化:
例如:
List
细节
-
泛型只能是引用类型
-
给定泛型的具体类型以后,可以传入泛型的类型或者子类型
-
泛型的使用形式:
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<>();//推荐这种写法
-
没有指定泛型,泛型默认就是Object
自定义泛型
- 普通成员可以使用泛型(属性和方法)
- 使用泛型的数组,不能初始化
- 静态方法中不能使用类的泛型
- 泛型类的泛型,会在创建对象的时候确定
- 如果在创建对象的时候没有指定泛型,默认就是Object
class Tiger<T,R,E>{
private String name;
private T t;
private R r;
private E e;//使用泛型定义属性
private T[] ts;//泛型数组不能初始化,泛型没有确定,不知道开辟多少内存空间
//不能使用泛型修饰静态属性和在静态方法中使用属性,静态属性随着类的加载而加载,泛型没有确定
//public static T t1;
// public static void m1(){
// System.out.println(t);
// }
public Tiger(String name, T t, R r, E e) {//在构造器中使用泛型
this.name = name;
this.t = t;
this.r = r;
this.e = e;
}
public T getT() {//在方法中使用泛型作为返回值
return t;
}
public void setT(T t) {//在方法中使用泛型作为形参类型
this.t = t;
}
}
自定义泛型接口
interface 接口名<泛型>{}
- 在接口中静态成员不能使用泛型
- 泛型接口的类型,在继承接口或者实现接口中确定
- 没有指定类型默认就是Object
自定义泛型方法
修饰符<泛型> 返回值 方法名(参数列表){}
1.泛型方法即可以定义在普通类中,也可以定义在泛型类中
2.当泛型方法被调用的时候,泛型就会被确定
3.public void eat(T t){},这个方法不是泛型方法,只是使用了泛型,修饰符后面没有
//普通类
class A{
//定义泛型方法,K,T是泛型
public <T,K> void eat(T t,K k){
System.out.println(t.getClass());
System.out.println(k.getClass());
}
}
class B<T>{
//定义泛型方法
public <E> void eat(T t,E e){
System.out.println(t.getClass());
System.out.println(e.getClass());
}
}
泛型的继承和通配符
-
泛型不具备继承性
List<Object> list = new ArrayList<String>();
这句语句是错误的,泛型不存在继承性 - 支持任意泛型类型
- 支持A类及A类的子类,规定了上限
- 支持A类以及A类的父类,不限于直接父类,规定了下限
public class Generic6 {
public static void main(String[] args) {
List<Object> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<AA> list3 = new ArrayList<>();
List<BB> list4 = new ArrayList<>();
List<CC> list5 = new ArrayList<>();
//List<?> list 支持任意类型泛型
printCollection1(list1);
printCollection1(list2);
printCollection1(list3);
printCollection1(list4);
printCollection1(list5);
//List<? extends AA> list 支持AA及AA的子类型泛型
printCollection2(list3);
printCollection2(list4);
printCollection2(list5);
//List<? super AA> list 支持AA和AA的父类型泛型
printCollection3(list1);
printCollection3(list3);
}
public static void printCollection1(List<?> list){
for (Object o : list) {
System.out.println(o);
}
}
public static void printCollection2(List<? extends AA> list){
for (AA aa : list) {
System.out.println(aa);
}
}
public static void printCollection3(List<? super AA> list){
for (Object o : list) {
System.out.println(o);
}
}
}
class AA{}
class BB extends AA{}
class CC extends BB{}