Java-泛型详解
- 泛型又称参数化类型,是JDK 5.0出现的新特性,解决数据类型的安全性问题
- 在类声明或实例化时只要制定好需要的具体的类型即可
- Java 泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生 ClassCastException异常。同时,代码更加简洁、健壮
- 泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值类型,或者是参数类型。
-
泛型的声明:
//interface 接口 <T> {} 和 class 类 <k , v> {} // 比如:List ,ArrayList 说明:其中 T,K,V 不代表值,而是表示类型;任何字母都可以。常用 T 表示 ,是Type的缩写
-
泛型的实例化:
要在类名后面指定类型参数的值(类型)。如:List<String> StrList = new ArrayList<String>(); Iterator<Customer> iterator = customers.iterator();
-
泛型使用的注意事项和细节
//1. intemface List<T>{} , public class HashSet<E>{}.. 等等 说明:T, E 只能是引用类型 ,不能是基本数据类型 看看下面语句是否正确?: List<Integer> list = new ArrayList<Integer>(); // 对 List<int> list2 = new ArrayList<int>(); // 错 //2.在给泛型指定具体类型后,可以传入该类型或者其子类类型3.泛型使用形式 List<Integer> list1 = new ArrayList<Integer>(); List<Integer> list2 = new ArrayList<>(); [说明:] //3.如果我们这样写 List list3 = new ArrayList();默认给它的 泛型是 [<E> E就是 Object ] //4. 在实际开发中我们往往简写 , 编译器会进行类型推断 List<Integer> List = new ArrayList<>();
-
基本语法
class 类名 <T,R...> { // 表示可以有多个泛型 成员 }
-
注意细节
//1、普通成员可以使用泛型(属性、方法) //2、使用泛型的数组,不能初始化 //3、静态方法中不能使用类的泛型 //4、泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型) //5、如果在创建对象时,没有指定类型,默认为Object
-
判断代码是否正确
MyGeneric<Double,String,Integer> g = new MyGeneric<>("john"); g.setT(10.9); g.setT("yy"); System.out.println(g); MtGeneric g2 = new MyGeneric("john~~"); g2.setT("yy"); System.out.println("g2=" + g2);
-
自定义泛型接口
基本语法: interface 接口名<T,R...> { } 注意细节: 1.接口中,静态成员也不能使用泛型(这个和泛型类的规定一样) 2.泛型接口的类型,在继承接口或者实现接口时确定 3.没有指定类型,默认为Object
-
自定义泛型方法
基本语法: 修饰符 <T,R..> 返回类型 方法名(参数列表) { } 注意细节: 1.泛型方法,可以定义在普通类中,也可以定义在泛型类中 2.当泛型方法被调用时,类型会确定 3.public void eat(E e) { }, 修饰符后,没有<T,R..> eat方法不是泛型方法,而是使用了泛型 package 泛型_; import java.util.ArrayList; public class CustomMethodGeneric { public static void main(String[] args) { Car car = new Car(); car.fly("String",10); } } // 泛型方法,也可以定义在普通类中,也可以定义在泛型类中 class Car { public void run() { // 普通方法 } // 说明 泛型方法 // 1. <T,R> 就是泛型 // 2. 是提供给 fly使用的 public <T,R> void fly(T t,R r) { // 泛型方法 System.out.println(t.getClass()); System.out.println(r.getClass()); // 测试 // T-> String, R-> ArrayList Fish<String, ArrayList> fish = new Fish<>(); } } class Fish <T,R> { // 泛型类 public void run () { } public<U,M> void eat(U u,M m){ // 泛型方法 } //hi 方法不是泛型方法, 是hi方法使用的类声明的泛型 public void hi(T t){ } // 泛型方法,可以使用类声明的泛型,也可以使用自己声明泛型 public<K> void hello(R r,K k) { } }
- 基本介绍:JUnit 是一个Java语言的单元测试框架
- 如果可以直接运行一个方法,就方便很多,并且给出相关信息。
定义个泛型类DAO<T>,在其中定义一个Map成员变量,Map的键为String类型,值为T类型。
分别创建以下方法:
(1) public void save(String id,T entity): 保存T类型的对象到Map成员变量中
(2) public T get(String id): 从map 中获取id 对应的对象
(3) public void update(String id,T entity):替换 map Pkey为id的内容,改为 entity对象
(4) public List<T> list():返回 map中存放的所有T对象
(5) public void delete(String id):W除指定id对象
定义一个User类:
该类包含: private成员变量(int类型) id, age; (String类型) name.
创建DAO类的对象,分别调用其save,get, update, list, delete 方法来操作User对象,使用Junit 单元测试类进行测试。
package homework01;
import org.junit.jupiter.api.Test;
import java.util.*;
public class Homework01 {
public static void main(String[] args) {
}
@Test
public void testList() {
// 这里给T 指定类型User
DAO<User> dao = new DAO<>();
dao.save("0001",new User(01,12,"Tom"));
dao.save("0002",new User(02,20,"jack"));
dao.save("0003",new User(03,15,"marry"));
List<User> list = dao.list();
System.out.println("list="+ list);
System.out.println("=======获取0001==========");
dao.get("0001");
System.out.println("=======删除0002===========");
dao.delete("0002");
System.out.println("=======修改0003===========");
dao.update("0003",new User(04,21,"smith"));
list = dao.list();
System.out.println("list="+ list);
}
}
class DAO<T> {
private Map<String,T> map = new HashMap<>();
public void save(String id,T entity){
map.put(id, entity);
}
public T get(String id) {
return map.get(id);
}
public void update(String id,T entity){
map.put(id,entity);
}
/* public Collection<T> list() {
return map.values();
}*/
public List<T> list() {
// 创建ArrayList
List<T> list=new ArrayList<>();
// 遍历Map
Set<String> keyset = map.keySet();
for (String key : keyset) {
list.add(map.get(key)); // 也可以直接使用本类的 get(String id)
}
return list;
}
public void delete(String id) {
map.remove(id);
}
@Override
public String toString() {
return "DAO{" +
"map=" + map +
'}';
}
}
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 int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}