一:泛型概述:
泛型机制:JDK1.5之后引入的一个新特性
是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊类型参数化类型,把类型当作参数一样的传递。
泛型的格式 : <数据类型> 这里的数据类型只能是引用数据类型
泛型好处:
(1): 把运行时期的问题提前到了编译期间
(2): 避免了强制类型转换
(3):优化了程序设计,解决了黄色警告线
注意:泛型只在编译期有效 但在运行期就擦除了
泛型的由来:(通过Object转型问题引入)
早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。
也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
泛型机制引入之前与泛型引用之后举例:
package org.westos.org.westos.Demo2;
//泛型机制没有引入之前的举例
//在创建对象或调用方法之前没有明确类型,所以在类定义和方法定义的过程中将所有的参数类型用Objice
//来声明. 其返回值也为Object类型.(接收时需要向下转型)
public class Demo {
public static void main(String[] args) {
Student student = new Student();//创建一个Student类
student.setName("小明");//调用student对象中的setName()方法,明确参数为String
student.setAge(10);//明确参数为Integer
String name = (String) student.getName();//getName()该方法的返回值为Object类型,所以需要向下转型
Integer age = (Integer) student.getAge();//getAge()该方法的返回值为Object类型,所以需要向下转型
System.out.println("name"+name);
System.out.println("age"+age);
}
}
//定义一个学生类
public class Student {
private Object name;
private Object age;
public Student() {
}
public Student(Object name, Object age) {
this.name = name;
this.age = age;
}
public Object getName() {
return name;
}
public void setName(Object name) {
this.name = name;
}
public Object getAge() {
return age;
}
public void setAge(Object age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name=" + name +
", age=" + age +
'}';
}
}
引入泛型机制之后:
package org.westos.demo2;
//泛型机制加入之后
public class MyDemo2 {
public static void main(String[] args) {
Teacher<String> stringTeacher = new Teacher<>();
stringTeacher.setName("abc");
String name = stringTeacher.getName();
Teacher<Integer> integerTeacher = new Teacher<>();
integerTeacher.setName(100);
integerTeacher.getName();
}
}
package org.westos.demo2;
public class Teacher<T> {
T name;
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
}
二:泛型类
泛型类概述: 把泛型定义在类上
定义格式: public class 类名<泛型类型1,…>
注意事项: 泛型类型必须是引用类型
三:泛型方法
泛型方法概述: 把泛型定义在方法上
定义格式: public <泛型类型> 返回类型 方法名(泛型类型 变量名);
泛型方法,当你在调用方法时,明确泛型的具体类型
四:泛型接口
泛型接口概述: 把泛型定义在接口上
定义格式: public interface 接口名<泛型类型>
泛型接口的子类: 第一种情况: 就是在定义子类的时候我们已经可以明确数据类型了
第二种情况: 就是在定义子类的时候我们还不知道到底使用神马数据类型.这个时候我们就需要将这个子 类也定义成泛型
五:泛型高级通配符
泛型通配符<?>: 任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E: 向下限定,E及其子类
? super E: 向上限定,E及其父类
泛型如果明确了数据类型以后,那么要求左右两边的数据类型必须一致
Collection<Object> col1 = new ArrayList<Object>() ;
Collection<Object> col2 = new ArrayList<Animal>() ;//报错
? 表示任意的数据类型
Collection<?> col5 = new ArrayList<Object>() ;
Collection<?> col6 = new ArrayList<Animal>() ;
? extends E : 向下限定 , ? 表示的是E或者E的子类
Collection<? extends Animal> col9 = new ArrayList<Object>() ;//报错
Collection<? extends Animal> col10 = new ArrayList<Animal>() ;
Collection<? extends Animal> col11 = new ArrayList<Dog>() ;
? super E: 向上限定 , ? 表示的是E或者E的父类
Collection<? super Animal> col13 = new ArrayList<Object>() ;
Collection<? super Animal> col14 = new ArrayList<Animal>() ;
Collection<? super Animal> col15 = new ArrayList<Dog>() ;//报错