一、泛型
1、泛型定义
泛型(generics)是JDK5.0以后的特性,提供了编译期间安全监测机制,它是将数据类型参数化的一种方式。 例如:在对方法进行编写参数列表时,以前我们需要知道方法的参数类型 ,现在使用泛型机制可以将方法的参数类型也作为 “未知的类型” ,在调用该方法时传递该类型。
2、泛型的使用
2.1 泛型类(generic class)
它是一种具有一个或多个类型变量的类,(一个变量可以有多种类型)
语法
public class 类<T>{
// 类里面的数据类型 和 方法返回值,以及方法的参数都可以使用T
// <>里面可以是任意大写字母
}
public class People<T> {
private T name;
private T sex;
public T getName() {
return name;
}
public People(T name,T sex){
this.name= name;
this.sex = sex;
}
public People(){
}
}
// 创建没有指定泛型的对象 ,它默认是Object类型
People obj= new People();
obj.setName("李四");
System.out.println(obj);
System.out.println(((String)obj.getName()).length());
// 创建泛型类的对象
People<String> people = new People<String>("张三","男");
System.out.println(people);
System.out.println(people.getName().length());
定义泛型的字母
T : Type: 变量类型
K: Key : 任意键的类型
V: Value : 任意值的类型
E:ELement 用于定义集合的元素类型
2.2 泛型接口(generic interface)
在接口中定义泛型,使接口的方法可以使用该泛型,实现类实现该接口时需要指定接口的类型、
语法:
public interface Genarator<T> {
public T getValue();
public void setValue(T s);
}
public class StringGenarator implements Genarator<String> {
private String name;
@Override
public String getValue() {
return name;
}
@Override
public void setValue(String s) {
this.name=s;
}
public class StudentGenarator implements Genarator<Student> {
private Student stu;
@Override
public Student getValue() {
return stu;
}
@Override
public void setValue(Student s) {
this.stu = s;
}
}
泛型接口的好处:
让接口的方法的返回值或参数类型 也参数化 (泛型)
2.3 泛型方法
a、为什么会使用泛型方法
当一个类中 只有某个方法需要使用泛型,而不是类的全部方法使用泛型,这时可以将泛型定义的范围缩小,通常我们可以定义进行泛型方法。
b、定义泛型方法
语法:
public class 普通类{
public <T> T getValue(){
}
public <T> void setValue(T t){
}
}
public class Convert {
/**
* 转成字符串的方法
* @param <T> : 任意类型
* @return
*/
public <T> String convertString(T t){
return t.toString();
}
public <K,V> V converted(K k){
return (V)k;// 强转的前提 是k -v 有关系
}
泛型的好处:
1、 可以对类的数据类型 写通用类型,提高代码的复用性 和 可扩展性
2.4 泛型通配符
在定义泛型时除了可使用大写字母表示一种泛型类以外,还可以使用通配符表示泛型类型,如下三种表示方法
:表示一种通用的泛型类,与相似
:表示 泛型类型是T的子类,或者是T
: 表示泛型类型是T的父类,或者是T
问题: 与
T t = new T() // 语法满足
? t = new ?() // 语法不满足
"< T >" 是一种确定的类型 , 可以表示定义泛型类或泛型方法
"<?>"是一种不确定的类型, 不能定义泛型类或泛型方法, 通常用于作为方法的形参
public class Dept<T> {
// 第一个员工
private T first;
// 第二个员工
private T second;
public class Employee {
private String ename;
public String getEname() {
return ename;
}
public class Manager extends Employee {
// 通过经理对象 给经理赋值名称
public Manager(String ename){
super(ename);
}
// 使用不确定的泛型类型 <?>
/**
*
* 这里的部门的泛型可以是任意类型
*/
public void showInfo(Dept<?> dept){
System.out.println(dept.getFirst());
}
/**
* @param dept 的泛型可以是Employee 或者继承自Employee
* @param dept
*/
public void showInfo2(Dept<? extends Employee> dept){
System.out.println(dept.getFirst());
System.out.println(dept.getSecond());
}
/**
*
* @param dept 的泛型必须是 Manager 或者 Manager的父类
*/
public void showInfo3(Dept<? super Manager> dept){
System.out.println(dept.getFirst());
System.out.println(dept.getSecond());
}
public static void main(String[] args) {
TestDept obj = new TestDept();
//创建部门对象
Dept<String> dept = new Dept();
dept.setFirst("员工1");
dept.setSecond("员工2");
obj.showInfo(dept);
// 在部门中添加 员工对象
Dept<Employee> dept2 = new Dept();
dept2.setFirst(new Employee("小强"));
dept2.setSecond(new Employee("小花"));
//这里的dept2的泛型是 Employee
obj.showInfo2(dept2);
Dept<Manager> dept3 = new Dept();
dept3.setFirst(new Manager("张经理"));
dept3.setSecond(new Manager("王经理"));
//这里的dept3的泛型是 Manager
obj.showInfo2(dept3);
// 调用时 参数的泛型必须是 Manager 或Manager的父类
obj.showInfo3(dept3);
obj.showInfo3(dept2);
}