文章目录
- 泛型generics
- 一.泛型简介
- 二.泛型类
- 1.泛型方法
- 三.泛型接口
- 四.泛型进阶
- 1.*<?>无解通配符*
- 2.上界通配符 < ? extends E>
- 3.下界通配符 < ? super E>
- 4.泛型擦除
泛型generics
一.泛型简介
JDK5引入,一种安全机制,编译时检测不匹配类型
- 特点:
- 将数据类型作为参数传递
- 编译时检查类型是否匹配
- 所有强制转换都是自动和隐私的
- 安全机制,提高代码复用率
[访问修饰符] class 类名<T,U,...> {T 泛型成员1 ;U 泛型成员2;...
}
//..................................
public instance Generics<T,K>{//大写表示数据类型,小写代表变量|参数List<T> employee;T queryAll();T add(T,t);int update(K,k);
}
-
常用泛型标识符:
通配符 说明 T (type) 表示具体的一个java类 K V (key value) 分别代表java键值中的Key Value E (element) 一般在集合中使用,表示集合中的元素类型 ? 表示不确定的 java 类型,经常出现在集合类中
本质泛型就是通配符, 替代数据
二.泛型类
[访问修饰符] class 类名<T,U,…> {
T 泛型成员1 ;
U 泛型成员2;
…
}//类型参数使用大写形式
1.泛型方法
泛型方法,是在调用方法的时候指明泛型的具体类型
三.泛型接口
public interface IBaseDao <T,K>{//T表示Employee类,K表示Integer类List<T> queryAll();int add(T t) throws IOException;int updateById(T t);int del(K k);T queryById(K k) ;
}
//IDeptDao接口继承泛型接口,使用其方法,自己内部方法省略,申明自己的泛型类型替代IBaseDao接口的T,K
public interface IDeptDao extends IBaseDao<Dept,Integer> {
// List<Dept> quarryAll();
//
// int addDept(Dept dept);
//
// int updateByIdDept(Dept dept);
//
// int quarryByIdDept(int id);
//
// int delDept(int id);
}
接口名末尾对泛型进行申明,用一个泛型接口规范实现类的操作
四.泛型进阶
除了用
<T>
表示泛型外,还有<?>
这种形式。<?>
被称作无限定的通配符
1.<?>无解通配符
T 是一个确定的类型,通常用于泛型类和泛型方法的定义。
?是一个不确定的类型,通常用于泛型方法的调用代码和形参,不能用于定义类和泛型方法
static Class<?>
返回类型forName(String className)
返回与给定字符串名称的类或接口相关联的 类对象。
List<?>
是一个未知类型的List
,不能向List<?>
中添加元素,但可以把List<String>
,List<Integer>
赋值给List<?>
List<?>
和List<Object >
是不一样的,<Object>
表示任意类型,<?>
表示未知类型,可以向List<Object>
中添加元素,但是不能把List<String>
赋值给List<Object>
public class MainApp {public static void main(String[] args) {List<Integer> intlist = new ArrayList<Integer>();intlist.add(11);intlist.add(22);intlist.add(33);printList(strList);//List<String> strList = new ArrayList<String>();strList.add("aa");strList.add("bb");strList.add("cc");printList(strList);}//不确定调用方法时传递的参数是什么类型,用?替代数据类型private static void printList(List<?> list) {for (Object obj : list) {System.out.println(obj);} }
}
2.上界通配符 < ? extends E>
package com.woniuxy.generate;import java.util.ArrayList;
import java.util.List;
//测试
public class MainApp {public static void main(String[] args) {List<Apple> applelist = new ArrayList<Apple>();applelist.add(new Apple());applelist.add(new Apple());applelist.add(new Apple());List<String> strList = new ArrayList<String>();strList.add("aa");strList.add("bb");strList.add("cc");printList(applelist);}
// 定义一个方法,可以接收Fruit,以及Fruit所有的子类的集合元素private static void printList(List<? extends Fruit> list) {for (Object obj : list) {System.out.println(obj);} }
//定义一个Fruit类 class Fruit {public void eat() {System.out.println("eat fruit");}@Overridepublic String toString() {return "Fruit []";} }//定义一个Fruit的子类Appleclass Apple extends Fruit {private String name;@Overridepublic String toString() {return "Apple []";}}
}
//代码解析:
//< ? extends E>, E表示父类Fruit,表示继承父类Fruit的元素或者父类Fruirt的参数传递,否则编译不成功
//入的类型是 E 或者 E 的子类
3.下界通配符 < ? super E>
返回类型 | 方法 |
---|---|
Class<? super E> | getSuperclass() 返回 类表示此所表示的实体(类,接口,基本类型或void)的超类 类(父类||父类上面的类) 。 |
/*** 定义一个方法,可以接收Apple,以及Apple所有的父类集合* 传递参数是Apple || Apple的父类* @param list */ private static void printList(List<? super Apple> list) {for (Object obj : list) {System.out.println(obj);} }
4.泛型擦除
泛型实现方式是擦拭法(Type Erasure)
//通过java反射的方式可以绕过泛型,Class<? extends List> clazz = intList.getClass();Method method = clazz.getMethod("add", Object.class);method.invoke(intList, "hello");
//通过java反射的方式可以绕过泛型,Class<? extends List> clazz = intList.getClass();Method method = clazz.getMethod("add", Object.class);method.invoke(intList, "hello");System.out.println(intList);