java----泛型
自定义泛型:
泛型只会在编译器存在,在运行期,会被擦除
泛型在类上定义,所以new一个对象的时候指定泛型类型,所以泛型必须和对象有关,和静态方法没有关系
public class Demo {
public static void main(String[] args){
Node<String> str = new Node<String>("ddd");
Node<Integer> num = new Node<>(10);
System.out.println(str);
System.out.println(num);
}
}
class Node<T>{
private T Date;
private Node(){};
public Node(T Data){
this.Date = Data;
}
public T getDate() {
return Date;
}
public void setDate(T date) {
Date = date;
}
@Override
public String toString() {
return "Node{" +
"Date=" + Date +
'}';
}
}
基本使用
import java.util.*;
public class Demo {
public static void main(String[] args){
Node<Number> num1 = new Node<Number>(20);
Node<Integer> num2 = new Node<>(10);
//Node.getData(num1); //不支持,不能进行转换
Node.getData(num2);
Node.getData2(num1); //使用了通配符,既可
//此时泛型可以是Number包扩他的所有的子类
Node<Short> num3 = new Node<Short>((short) 11);
Node.getData3(num1);
Node.getData3(num3);
//此时泛型可以是Byts包扩他的所有的父类
Node<Short> num4 = new Node<Short>((short) 11);
Node.getData3(num1);
Node.getData3(num4);
//泛型方法定义
String arr[] = {"1","2","3"};
//好像不能传入一个集合
System.out.println(Arrays.toString(Node.fun(arr,1,2)));
//泛型嵌套
Map<Integer,String> map = new HashMap<>();
map.put(1,"k");
map.put(2,"v");
map.put(3,"c");
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry entry:entries){
System.out.println(entry);
}
}
}
class Node<T>{
private T Date;
private Node(){};
public Node(T Data){
this.Date = Data;
}
public T getDate() {
return Date;
}
public void setDate(T date) {
Date = date;
}
@Override
public String toString() {
return "Node{" +
"Date=" + Date +
'}';
}
public static void getData(Node<Integer> node){
System.out.println(node.getDate());
}
//使用通配符定义泛型类型,只能输出,不能修改
public static void getData2(Node<?> node){
//node.setDate(20); //报错
System.out.println(node.getDate());
}
//设置上限,同样不能设置
public static void getData3(Node<? extends Number> node){
//node.setDate(20); //报错
System.out.println(node.getDate());
}
//设置下限,包扩Byte,以及所有的父类
public static void getData4(Node<? super Byte> node){
//node.setDate(20); //报错
System.out.println(node.getDate());
}
public static <T> T[] fun(T[] array,int i1,int i2){
T temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
return array;
}
}
泛型的继承
class Test<T extends BaseEntity>
限制为了T (传入的)泛型必须继承BaseEntity,起到一部分的限制作用,为了不让T为任意的对象
可以通过查看HashMap源码来理解
public class Demo{
public static void main(String[] args) {
HashMap<A, String> aStringHashMap = new HashMap<>(new HashMap<B,String>());
}
}
class A{}
class B extends A{};
反射操作泛型
因为泛型在运行时就会被擦除,所以当一个类加载类内存的时候,就没有泛型了,反射直接读取泛型是读取不到的、
为了通过反射操作这些类型以迎合实际开发的需要,Java就新增了ParameterizedType,GenericArrayType,TypeVariable 和WildcardType几种类型来代表不能被归一到Class类中的类型但是又和原始类型齐名的类型。
ParameterizedType:表示一种参数化的类型,比如Collection <String>
GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型
TypeVariable:是各种类型变量的公共父接口
WildcardType:代表一种通配符类型表达式,比如?,?extends Number,?super Integer【wildcard是一个单词:就是“通配符"】
public class Test1 {
public static void test01(Map<String,Integer> map){
}
public static Map<String,Integer> test02(){
return null;
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class<Test1> test1Class = Test1.class;
Method test01 = test1Class.getDeclaredMethod("test01", Map.class);
Type[] types = test01.getGenericParameterTypes();
for (Type t:types){
System.out.println(t);
//java.util.Map<java.lang.String, java.lang.Integer>
Type[] actualTypeArguments = ((ParameterizedType) t).getActualTypeArguments();
for (Type actualT:actualTypeArguments){
System.out.println(actualT);
//class java.lang.String
//class java.lang.Integer
}
}
Method test02 = test1Class.getDeclaredMethod("test02");
Type genericReturnType = test02.getGenericReturnType();
System.out.println(genericReturnType);
//java.util.Map<java.lang.String, java.lang.Integer>
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualT:actualTypeArguments){
System.out.println(actualT);
//class java.lang.String
//class java.lang.Integer
}
}
}
}
泛型使用
功能1:调用方法,参数传入泛型,返回值
<T> T表示返回值是一个泛型,传递啥,就返回啥类型的数据,而单独的T就是表示限制你传递的参数类型,这个案例中,通过一个泛型的返回方式,获取每一个集合中的第一个数据, 通过返回值<T> T 和T的两种方法实现
@Service
public class RedisService {
public <T> T get(KeyPrefix prefix, String token, Class<T> clazz) {
Jedis jedis = null;
try {
String realKey = "xx";
String str = jedis.get(realKey);
T t = stringToBean(str, clazz);
return t;
} finally {
returnToPool(jedis);
}
}
}
不传入泛型,返回类型是泛型
class B{
public static <T> List<T> list(){
List<T> list = null;
return list;
}
public void c(){
//用什么类型接收T,存在问题
List<String> a = B.list();
List<Integer> b = B.list();
}
}
功能2:限制传入类型
public class Demo2<T> {
public static void main(String[] args) {
//限制T 为String 类型
Demo2<String> demo = new Demo2<String>();
//获取string类型
List<String> array = new ArrayList<String>();
array.add("test");
array.add("doub");
String str = demo.getListFisrt(array);
System.out.println(str);
}
private T getListFisrt(List<T> data) {
if (data == null || data.size() == 0) {
return null;
}
return data.get(0);
}
}
泛型
传入泛型,返回Boolean
public <T> Boolean set(KeyPrefix prefix, String key, T value) {
return true;
}

浙公网安备 33010602011771号