• java泛型基础


    泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 这种参数类型可以用在类、接口和方法的创建中, 分别称为泛型类、泛型接口、泛型方法.  Java语言引入泛型的好处是安全简单.

    今天就从以下几个方面介绍一下java的泛型: 基础, 泛型关键字, 泛型方法, 泛型类和接口.

    基础:

      通过集合的泛型了解泛型的基本使用

        public void testBasis(){
            List<String> list = new ArrayList<String>();
    //        new ArrayList<int>();
        }
        
     //这是最基本的泛型使用, 就不多说了, 不过要注意的是泛型只能是引用数据类型, 不能是基本类型, 而且泛型只在编译期有效, 在编译后的class文件中是不存在泛型信息的 

     注意: 泛型只在编译期有效, 在编译后的class文件中是不存在泛型信息的 

    泛型关键字:

      通配符?表示任意引用类型, extends关键字表示子类及其本身, super关键字是表示父类及其本身. 通过一个例子看一下, 解释说明都在例子中

        public void testKeyWord() throws Exception {
            //实例化参数类型必须指明具体类型
            List<?> list = new ArrayList<String>();
            //由于list中类型不明确, 所以不能进行添加操作
    //        list.add("sk");
            
            //通配符?表示任意引用类型
            List<List<?>> list1 = new ArrayList<List<?>>();
            //list1的参数化类型是一个List, 而这个List也是一个参数化类型, 它的类型是任意类型, 所以list1可以添加任意List类型对象
            list1.add(new ArrayList<Object>());
            list1.add(new ArrayList<String>());
            
            //实例化list2时指明了类型参数List, 只不过这个List是一个泛型类型
            //从这里可以看到关键字extends的用法, 其实就是继承, 如下这里的list2中的参数化类型List(在这里记为paramList)的参数化类型是继承自Number的
            //所以在list2在添加的时候只能添加参数化类型为Number及其子类的paramList
            List<Integer> l1 = new ArrayList<Integer>();
            List<Number> l2 = new ArrayList<Number>();
            List<Object> l3 = new ArrayList<Object>();
            List<List<? extends Number>> list2 = new ArrayList<List<? extends Number>>();
            list2.add(l1);
            list2.add(l2);
    //      list2.add(l3);    //这里使用了extends关键字, 所以不能添加Number的父类
            
            //相信大家也猜到了, 既然extends关键字表示子类及其本身, 那么super关键字是表示父类及其本身, 是的, 没错
            //和上面的不一样了, l1不能添加, 因为Integer是Number的子类, 并不是Number的父类
            List<List<? super Number>> list3 = new ArrayList<List<? super Number>>();
    //      list3.add(l1);    //这里使用了super关键字, 所以不能添加Number的子类
            list3.add(l2);
            list3.add(l3);
        }

    泛型方法:

      java中任何类型必须先定义才能使用, 泛型也是如此. 既然要使用泛型作为参数, 所以要先定义, 泛型的定义在访问修饰符和返回类型之间, 注意不要掉了尖括号

        //无返回值有参的方法, 参数为泛型
        public <T> void show(T t){
            System.out.println("t-=-=" + t);
        }
        
        //有返回值的有参方法, 只有一个参数化类型, 这里定义泛型的方式和上面一样, 也是先定义后使用, 只不过这里的返回类型是泛型
        public <T> T get(T t){
            return t;
        }
        
        //有返回值的有参方法, 有多个参数化类型, 这里以两个为例
        public <T, K> K get(T t,   K k){
            return k;
        }
        
        @Test
        public void testGeneric() throws Exception {
            show(3);
            show("generic");
            System.out.println("----------------");
            
            System.out.println("我返回Integer类型-" + get(4));
            System.out.println("我返回String类型-" + get("returnGeneric"));
            System.out.println("------------------");
            
            System.out.println("我返回String类型-" + get(1,   "a"));
            System.out.println("我返回Integer类型-" + get("b",   2));
        }

      本来想写无参的泛型方法, 可是写着写着感觉那样没有什么意义, 不知道各位有什么见解.

    泛型类和接口:

      写泛型类的时候只需要在类名后面加上泛型即可, 就像这样

    public class GenericClass<T> {
        public T get(T t){
            return t;
        }
        
        public void scr(T t){
            System.out.println(t);
        }
    
        public void show(){
            GenericClass<Integer> gc = new GenericClass<Integer>();
    //      GenericClass<T> gc1 = new GenericClass<T>();
            gc.get(3);
            gc.scr(5);
            //下面2个会报错
    //      gc1.get(3);
    //      gc1.scr(5);
        }
    }

      从上面的例子中可以看到, 参数化类型是在创建对象的时候具体化的, 那么除此之外, 还可以再什么时候具体化参数化类型呢?

      如果是在继承或实现中, 可以在子类或实现类中确定具体类型

      泛型的应用, 请参看使用java泛型设计通用方法

  • 相关阅读:
    css如何设置div中的内容垂直居中?
    有哪些sql优化工具
    XSS攻击
    java的HashSet 原理
    复杂度O(n)计算
    Kubernetes(K8s)基础知识(docker容器技术)
    Golang glog使用详解
    教你如何找到Go内存泄露【精编实战】
    Linux生产环境上,最常用的一套“AWK“技巧【转】
    Go 程序的性能监控与分析 pprof
  • 原文地址:https://www.cnblogs.com/pdzbokey/p/6149604.html
Copyright © 2020-2023  润新知