总结:
泛型类、泛型接口;泛型方法。见OrderTest.java
/**
* 自定义泛型类
*
* @param <T>
*/
public class Order<T> {
T OrderName;
T OrderAge;
// 类的内部结构就可以使用类的泛型
T OrderT;
// 静态方法中不能使用类的泛型。
// public static void show(T OrderT){
// System.out.println(OrderT);
// }
public Order() {
// 编译不通过
//T[] arr = new T[10];
// 通过
T[] arr = (T[]) new Object[10];
}
/*
泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
换句话说,泛型方法所属的类是不是泛型类都没有关系。
泛型方法,可以声明为静态的,原因:泛型参数是在调用方法时确定的,并非在实例化类是确定。
*/
public <E> List<E> cpList(E[] arr) {
ArrayList<E> list = new ArrayList<>();
for (E e : arr) {
list.add(e);
}
return list;
}
public Order(T orderName, T orderAge) {
OrderName = orderName;
OrderAge = orderAge;
}
public void OrderT() {
}
public void setOrderT(T orderT) {
OrderT = orderT;
}
}
// 异常类不能声明为泛型类
//class MyException<T> extends Exception{}
/**
* 如何自定义泛型结构:泛型类、泛型接口;泛型方法。
*
* 1. 关于自定义泛型类、接口:
*/
public class OrderTest {
@Test
public void test1() {
// 如果定义了泛型类,实例化没有指定类的泛型,则默认为此泛型类型为Object类型
// 要求:如果定义了类是带泛型的,建议实例化时要指明类的泛型。
Order order = new Order();
order.setOrderT("Tom");
// 建议:实例化时指明类的泛型。
Order<Integer> order1 = new Order<>();
order1.setOrderT(123);
SubOrder<String> order2 = new SubOrder<>();
order2.test2("Tom");
}
@Test
public void test2() {
ArrayList<Integer> list1 = null;
ArrayList<String> list2 = null;
// 泛型不同的引用不能互相赋值
//list1 = list2;
String s1 = null;
String s2 = null;
s1 = s2;
}
// 测试泛型方法
@Test
public void test3() {
Order<String> order = new Order<>();
// 泛型方法在调用时,指明泛型参数的类型。
Integer[] integers = new Integer[]{1, 2, 3, 4};
List<Integer> list = order.cpList(integers);
System.out.println(list);
}
}
class SubOrder<T> extends Order<Integer> { //SubOrder<T>:仍是泛型类。
public void test1() {
SubOrder<Integer> subOrder = new SubOrder<>();
// 由于子类在继承带有泛型的父类时,指明了泛型类型。则实例化子类对象时,不在需要指明泛型。
subOrder.OrderT();
}
public T test2(T name) {
return name;
}
}
静态方法 中不能使用类的泛型。
[访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常
public class DAO {
public <E> E get(int id, E e) {
E result = null;
return result;
}
}
class Father<T1, T2> { }
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father {// 等价于class Son extends Father<Object,Object>{
}
// 2)具体类型
class Son2 extends Father<Integer, String> { }
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2> { }
// 2)部分保留
class Son4<T2> extends Father<Integer, T2> { }
class Father<T1, T2> {}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son<A, B> extends Father{//等价于class Son extends Father<Object,Object>{
}
// 2)具体类型
class Son2<A, B> extends Father<Integer, String> { }
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2, A, B> extends Father<T1, T2> { }
// 2)部分保留
class Son4<T2, A, B> extends Father<Integer, T2> { }
class Person<T> {
// 使用T类型定义变量
private T info;
// 使用T类型定义一般方法
public T getInfo() {return info;}
public void setInfo(T info) {this.info = info; }
// 使用T类型定义构造器
public Person() { }
public Person(T info) {this.info = info;}
// static的方法中不能声明泛型
//public static void show(T t) { }
// 不能在try-catch中使用泛型定义
//public void test() {
//try {} catch (MyException<T> ex) { }
//}
}
泛型在继承方面的体现:
虽然类A是类B的父类,但是 G 和 G 二者不具备子父类关系,二者是并列关系。
补充:如果类A是类B的父类,那么 A
public class GenericTest {
/*
1. 泛型在继承方面的体现
虽然类A是类B的父类,但是 G<A> 和 G<B> 二者不具备子父类关系,二者是并列关系。
补充:如果类A是类B的父类,那么 A<G>是B<G> 的父类。
*/
@Test
public void test1(){
Object obj1 = null;
String obj2 = null;
obj1 = obj2;
Object[] str1 = null;
String[] str2 = null;
str1 = str2;
// 编译不通过
// Date date = new Date();
// obj2 = date;
List<Object> list1 = null;
List<String> list2 = null;
// 此时list1和list2不具备子父类关系
// 编译不通过
//list1 = list2;
/*
反证法:
假设list1 = list2;
list1.add(123); 导致list2混入非String的数据,出错。
*/
}
@Test
public void test2(){
Collection<String> list1 = null;
List<String> list2 = null;
list1 = list2;
}
通配符:?
类A是类B的父类,G 和 G 是并列关系,二者的共同父类是G<?>
限制条件的通配符的使用:
? extend A: G<? extend A> 可以作为G和G的父类,其中B是A的子类。
? super A: G<? super A> 可以作为G和G的父类,其中B是A的父类
/*
类A是类B的父类,G<A> 和 G<B> 是并列关系,二者的共同父类是G<?>
*/
@Test
public void test3(){
List<Object> list1 = null;
List<String> list2 = null;
List<?> list = null;
list = list1;
list = list2;
ArrayList<String> list3 = new ArrayList<>();
list3.add("AA");
list3.add("BB");
list3.add("CC");
list = list3;
//添加(写入):对于List<?> 就不能向其他内部添加数据。
//除了添加null之外。
// list.add("DD");
list.add(null);
//获取(读取):允许读取数据,读取的数据类型为Object。
Object o = list.get(0);
System.out.println(o);
// 编译通过
// print(list1);
// print(list2);
}
public void print(List<?> list){
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
/*
3. 限制条件的通配符的使用
? extend A: G<? extend A> 可以作为G<A>和G<B>的父类,其中B是A的子类。
? super A: G<? super A> 可以作为G<A>和G<B>的父类,其中B是A的父类
*/
@Test
public void test4(){
List<? extends Person> list1 = null; // 最下限是Person (Person<=)
List<? super Person> list2 = null; // 最上限是Person (<=Person)
List<Student> list3 = null;
List<Person> list4 = null;
List<Object> list5 = null;
list1 = list3;
list1 = list4;
// list1 = list5;
// list2 = list3;
list2 = list4;
list2 = list5;
}
}
class Person{}
class Student extends Person{}
/**
* 定义个泛型类 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 对象
* @param <T>
*/
public class DAO <T>{
private 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){
if (map.containsKey(id)){
map.put(id,entity);
}
}
//返回 map 中存放的所有 T 对象
public List<T> list(){
//错误的
// Collection<T> values = map.values();
// return (List<T>) values;
//正确的
ArrayList<T> list = new ArrayList<>();
Collection<T> values = map.values();
for (T t : values) {
list.add(t);
}
return list;
}
//删除指定 id 对象
public void delete(String id){
map.remove(id);
}
}
/**
* 定义一个 User 类:
* 该类包含:private 成员变量(int 类型) id,age;(String 类型)name。
*/
public class User {
private int id;
private int age;
private String name;
public User() {}
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 + ‘\‘‘ +
‘}‘;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (id != user.id) return false;
if (age != user.age) return false;
return name != null ? name.equals(user.name) : user.name == null;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + age;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
/**
* 定义一个测试类:
* 创建 DAO 类的对象, 分别调用其 save、get、update、list、delete 方
* 法来操作 User 对象,
* 使用 Junit 单元测试类进行测试。
*/
public class DAOTest {
public static void main(String[] args) {
DAO<User> dao = new DAO<>();
dao.save("1001",new User(1001,48,"三张"));
dao.save("1002",new User(1002,24,"四李"));
dao.save("1003",new User(1003,45,"五王"));
dao.save("1004",new User(1004,36,"麻二"));
User user1 = dao.get("1002");
System.out.println(user1); //User{id=1002, age=24, name=‘四李‘}
dao.update("1003",new User(2003,66,"王孙"));
List<User> list1 = dao.list();
System.out.println(list1);
dao.delete("1001");
System.out.println("---------------------------------");
List<User> list = dao.list();
for (User user : list) {
System.out.println(user);
}
}
}
原文:https://www.cnblogs.com/kin02/p/14884041.html