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;
    }

  

posted @ 2019-04-23 18:27  小名的同学  阅读(167)  评论(0编辑  收藏  举报