详解自定义泛型
1、自定义泛型类
(1) 语法:Class 类名<T, R…>{//…表示可以有多个泛型成员},T,R和M为泛型的标识符,一般是单个大写字母。
(2) 使用注意事项:
① 普通成员(属性、方法)可以是使用泛型;
② 使用泛型的数组,不能初始化;
③ 静态方法中不能使用类的泛型,因为静态是和类相关的,在类加载时,对象还没有创建,所以,如果静态方法和静态属性使用了泛型,JVM就无法完成初始化;
④ 泛型类的类型是在创建对象时确定的(因为创建对象时,需要指定确定类型);
⑤ 如果在创建对象时,没有指定类型,默认为Object。
2、自定义泛型接口
(1) 语法:Interface 接口名<T, R…>{ }
(2) 使用注意事项:
① 接口中,静态成员也不能使用泛型;
② 泛型接口的类型,在继承接口或者实现接口时确定;
③ 没有指定类型,默认为Object。
3、自定义泛型方法
(1) 语法:修饰符<T, R…>返回类型 方法名(参数列表){ }
(2) 使用注意事项:
① 泛型方法可以定义在普通类中,也可以定义在泛型类中;
② 当泛型被调用时,类型会确定;
③ Public void eat(E e){ },修饰符后没有<T, R…>,所以eat方法不是泛型方法,而是使用了泛型。
4、泛型的继承和通配符
使用注意事项:
① 泛型不具备继承性,例如,List list = new ArrayList( )错误;
② <?>:支持任意泛型
③ <? extends A>:支持A类以及A类的子类,规定了泛型的上限
④ <? Super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限。
5、案例
5.1 问题描述
(1) 定义个泛型类DAO,在其中定义一个Map成员变量,Map的键为String类型,值为T类分别创建以下方法:
① public void save(String id,T entity):保存T类型的对象到 Map成员变量中
② public T get(String id):从map中获取id对应的对象
③ public void update(String id,T entity):替换map 中key为id的内容,改为entity对象
④ public List list():返回map中存放的所有T对象
⑤ public void delete(String id):删除指定id对象
(2)定义一个User类:
该类包含: private成员变量(int类型) id, age;(String类型) name.
创建DAO类的对象,分别调用其save、get、update、list、delete方法来操作User对象,使用Junit 单元测试类进行测试。
5.2 代码编写
(1) 创建User类
class User{
private int id;
private int age;
private String name;
public User(int id,int age,String name){
this.id = id;
this.age = age;
this.name = name;
}
public void setId(int id){
this.id = id;
}
public int getId(){
return id;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public String toString(){
return "Usre{" +
"编号:" +id +"\t"+
"年龄:"+age +"\t"+
"姓名:" + name +
'}'+"\n";
}
}
(2) 创建泛型类DAO
class DAO<T>{ }
① 定义一个Map成员变量,Map的键为String类型,值为T类
Map<String,T> map = new HashMap<>();
② 创建方法public void save(String id,T entity):保存T类型的对象到 Map成员变量中
/*保存T类型的对象到 Map成员变量中*/
public void save(String id,T entity){
map.put(id,entity);
}
③ 创建方法public T get(String id):从map中获取id对应的对象
/*从map中获取id对应的对象*/
public T get(String id){
return map.get(id);
}
④ 创建方法public void update(String id,T entity):替换map中key为id的内容,改为entity对象
/*调用DAO类的update方法来操作User对象*/
dao.update("001",new User(1,31,"DMS1"));
System.out.println("=====修改后=====");
System.out.println(dao.get("001"));
⑤ 创建方法public List list():返回map中存放的所有T对象
/*返回map中存放的所有T对象*/
//遍历map[k-v],将map的所有value(T entity),封装到ArrayList返回
public List<T> list(){
ArrayList<T> arrayList = new ArrayList();
Set<String> set = map.keySet();
for(String key:set){
arrayList.add(map.get(key));
}
return arrayList;
}
⑥ 创建方法public void delete(String id):删除指定id对象
/*删除指定id对象*/
public void delete(String id){
map.remove(id);
}
(3) 使用Junit 单元测试类进行测试
@Test
public void testList(){
DAO<User> dao = new DAO();
}
① 调用DAO类的save方法来操作User对象
/*调用DAO类的save方法来操作User对象*/
dao.save("001",new User(1,21,"DMS"));
dao.save("002",new User(2,22,"LHX"));
dao.save("003",new User(3,23,"LSY"));
dao.save("004",new User(4,24,"SMG"));
② 调用DAO类的get方法来操作User对象
/*调用DAO类的get方法来操作User对象*/
System.out.println(dao.get("001"));
③ 调用DAO类的update方法来操作User对象
/*调用DAO类的update方法来操作User对象*/
dao.update("001",new User(1,31,"DMS1"));
System.out.println("=====修改后=====");
System.out.println(dao.get("001"));
④ 调用DAO类的list方法来操作User对象
/*调用DAO类的list方法来操作User对象*/
System.out.println(dao.list());
⑤ 调用DAO类的delete方法来操作User对象
/*调用DAO类的delete方法来操作User对象*/
dao.delete("001");
System.out.println("=====删除后=====");
System.out.println(dao.list());
5.3 运行结果
5.4 完整程序
package com.hspedu.homework;
import org.junit.jupiter.api.Test;
import java.util.*;
/*1.编程题Homework01.java
(1)定义个泛型类DAO<T>,在其中定义一个Map成员变量,Map的键为String类型,值为T类分别创建以下方法:
① public void save(String id,T entity):保存T类型的对象到 Map成员变量中
② public T get(String id):从map中获取id对应的对象
③ public void update(String id,T entity):替换map中key为id的内容,改为entity对象
④ public List<T> list():返回map中存放的所有T对象
⑤ public void delete(String id):删除指定id对象
(2) 定义一个User类:
该类包含: private成员变量(int类型) id, age;(String类型) name.
创建DAO类的对象,分别调用其save、get、update、list、delete方法来操作User对象,使用Junit 单元测试类进行测试。
*/
@SuppressWarnings({"all"})
public class GenericHomework {
private static void main(String[] args){
}
/*使用Junit 单元测试类进行测试*/
@Test
public void testList(){
DAO<User> dao = new DAO();
/*调用DAO类的save方法来操作User对象*/
dao.save("001",new User(1,21,"DMS"));
dao.save("002",new User(2,22,"LHX"));
dao.save("003",new User(3,23,"LSY"));
dao.save("004",new User(4,24,"SMG"));
/*调用DAO类的get方法来操作User对象*/
System.out.println(dao.get("001"));
/*调用DAO类的update方法来操作User对象*/
dao.update("001",new User(1,31,"DMS1"));
System.out.println("=====修改后=====");
System.out.println(dao.get("001"));
/*调用DAO类的list方法来操作User对象*/
System.out.println(dao.list());
/*调用DAO类的delete方法来操作User对象*/
dao.delete("001");
System.out.println("=====删除后=====");
System.out.println(dao.list());
}
}
/*(1)定义个泛型类DAO<T>,在其中定义一个Map成员变量,Map的键为String类型,值为T类分别创建以下方法:*/
class DAO<T>{
Map<String,T> map = new HashMap<>();
/*保存T类型的对象到 Map成员变量中*/
public void save(String id,T entity){
map.put(id,entity);
}
/*从map中获取id对应的对象*/
public T get(String id){
return map.get(id);
}
/*替换map中key为id的内容,改为entity对象*/
public void update(String id,T entity){
map.put(id,entity);
}
/*返回map中存放的所有T对象*/
//遍历map[k-v],将map的所有value(T entity),封装到ArrayList返回
public List<T> list(){
ArrayList<T> arrayList = new ArrayList();
Set<String> set = map.keySet();
for(String key:set){
arrayList.add(map.get(key));
}
return arrayList;
}
/*删除指定id对象*/
public void delete(String id){
map.remove(id);
}
}
class User{
private int id;
private int age;
private String name;
public User(int id,int age,String name){
this.id = id;
this.age = age;
this.name = name;
}
public void setId(int id){
this.id = id;
}
public int getId(){
return id;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public String toString(){
return "Usre{" +
"编号:" +id +"\t"+
"年龄:"+age +"\t"+
"姓名:" + name +
'}'+"\n";
}
}