• 第15章_泛型:



    0:优秀博客:https://www.cnblogs.com/fengmingyue/p/6087031.html
    1:泛型的目的之一:用来指定容器要持有什么类型的对象,而且由编译器来保证类型的正确性。
    2:泛型案例:
    例1:“泛型类
    public class Holder<T>{
            private T t;
            public Holder(T t){this.t = t;}
            public T getHolder(){return this.t;}
    }
    3:使用泛型告诉编译器你想使用什么类型,然后由编译器处理细节,在类上定义的泛型,不能在今天方法中使用
    4:“元组”:将一组对象存储在一个对象中。通常元组具有任意长度,可以存储任意类型。(也叫做信使)
    5:一段有意思的代码:
        Class c1 = New ArrayList<String>().getClass();
        Class c2 = New ArrayList<Integer>().getClass();
        System.out.println(c1 == c2);   //true     
     **这里需要注意:在泛型代码内部,无法获取任何有关泛型类型参数的信息。
    6:java泛型是使用擦除来实现的。当你使用泛型时,任何具体的类型都被擦除了。
    你唯一知道的是:你规范了一个类型。因此上面的ArrayList<String>和ArrayList<Integer>都被擦除成为了ArrayList类型。
       泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。

    7:“边界”:类似<T extends HasF>这种重用了extends的泛型。它表示规范的类型是继承自HasF。
    8:泛型在擦除时,将擦除到第一个边界(可能有多个边界),<T extends HasF>会擦除到HasF,这就像在类的声明中使用HasF代替了T一样。
    9:泛型在java1.0中是没有的,由于之后要添加进去,所以使用了擦除这种折中的解决方案。
    10:“泛型方法”:
    例1:
        private static<T> void exchange(T[] arr, int i, int j) {
                T temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    例2:
        public <T> T get(T[] ts) {
                return ts[ts.length / 2];
        }
    11:通配符“?”
        public static void fun(List<Object> list) {…}
        List<String> list1 = new ArrayList<String>();
        List<Integer> list2 = new ArrayList<Integer>();
        fun(list1);//编译不通过
        fun(list2);//编译不通过
        //上面的调用都是编译不通过的!这说明想写一个即可以打印list1,又可以打印list2的方法是不可能的!
    public static void fun(List<?> list) {…} //如果这里不使用泛型会警告,使用通配符即可。
    但是使用通配符后,不能确定要类型,相关方法不能使用,例如:list.add("字符串");编译不通过。

      通配符有 3 种形式。

        1、<?> 被称作无限定的通配符

        2、<? extends T> 被称作有上限的通配符

        3、<? super T> 被称作有下限的通配符

    12:基本类型不能写在泛型中(例如:ArrayList<int>)。
    13:一个类不能同时实现一个泛型的两个变体。
    例如:
        Interface A<T>{}
        Class B implements A<B>{}
        Class C extends B implements A<C>{}
        //由于擦除的原因,会将A<B>和A<C>都变为A。这样意味着C实现了两次A接口,编译不通过。
    //但是将A接口的两个实现的泛型都去掉后,编译通过。(在使用java的一些基本接口时会遇到:Comparable<T>)
    14:泛型方法重载
    一下代码不能编译通过:
    public Class A(){
                void f(List<W> w);
                void f(List<V> v)
    }
            //由于擦除的原因,上面的两个方法产生的签名是一样的
    ¥¥此时正好听到了这首歌的这句话,颇有感慨。《明天会更好》:青春不解红尘。
    15:“混型”:最基本的概念是:混合多个类的能力。
    16、参数类型化:
    //类型参数化
    public class Cache<T> {
        T value;
    
        public Object getValue() {
            return value;
        }
    
        public void setValue(T value) {
            this.value = value;
        }
    
    }
    
    

     代码:

    泛型类:
    class ClassGenericity<T> {
        //在类里面可以直接使用T的类型
        T aa;
        public void test11(T bb) {
            //................
        }
        //静态方法 在类上面定义的泛型,不能再静态方法里面使用
        public static <A> void test12(A cc) {
            //..................
        }
    
    
    泛型使用在参数和返回值中。
    public class MethodGenericity {
        //泛型使用在参数中
        private static<T> void exchange(T[] arr, int i, int j) {
            T temp=arr[i];
            arr[i]=arr[j];
            arr[j]=temp;
        }
        //泛型使用在返回值中
         public <T> T get(T[] ts) {
             return ts[ts.length / 2];
         }
    }
    
    
    通配符
    public static void fun(List<?> list) {…}
    
    
    带有上边界的通配符
    public static void fun(List<? extends Number> list) {…}
    fun(new ArrayList<Integer>());//ok
    fun(new ArrayList<Double>());//ok
    fun(new ArrayList<String>());//不ok
    
    
    带有下边界的通配符
    public static void fun(List<? super Integer> list) {…}
    fun(new ArrayList<Integer>());//ok
    fun(new ArrayList<Number>());//ok
    fun(new ArrayList<Object>());//ok
    fun(new ArrayList<String>());//不ok


     
  • 相关阅读:
    hdu2438 三分
    hdu3786 找出直系亲属 水题
    hdu3786 找出直系亲属 水题
    hdu4561 连续最大积
    hdu4561 连续最大积
    hdu4604 不错的子序列问题
    hdu4604 不错的子序列问题
    hdu4450 不错的贪心
    hdu1722 切蛋糕
    hdu3768 spfa+全排列
  • 原文地址:https://www.cnblogs.com/Xmingzi/p/8717059.html
Copyright © 2020-2023  润新知