zoukankan      html  css  js  c++  java
  • Java对泛型的支持(二)

    JAVA中基本的泛型语法元素大致有三种:限制泛型可用类型使得类型通配符,以及泛型的继承。下面将分别对这三种语法进行介绍。


    1、限制泛型可用类型

    我们在定义泛型类时,默认的是可以使用任何类型来实例化泛型类中的类型持有者。我们也可以指定某种类型,使得此泛型类只能通过这种类型或其子类,或实现这个接口的类来实例化类型持有者。

    我们在定义类型持有者时,使用extends关键字来进行限制,例如我们可以这样定义泛型类:

    public class LimitDemo<T extends List>
    {
    }

    这表示类型持有者T所代表的类型 必须是一个实现了List接口的类型。所以我们要这样产生LimitDemo类的实例:

    LimitDemo<ArrayList> demo = new LimitDemo<ArrayList>();

    因为ArrayList是实现了List接口的类,所以这样写是合法的。如果不是实现List接口的类:

    LimitDemo<String> demo = new LimitDemo<String>(); // String没有实现List接口

    编译器就会报出 “String类型不在T范围内” 的错误:


    事实上,当我们不用extends关键字来限制泛型类对象时,编译器默认的是Object类下所有的子类都可以实例化类型持有者。即:

    public class LimitDemo<T>{}

    等价于:

    public class LimitDemo<T extends Object>{}



    2、类型通配符

    如果有一个引用名demo,我们希望demo既能引用WildDemo<String>类型,又能引用WildDemo<Integer>类型,该如何实现呢?

    不使用通配符的话,我们只能分别定义两个变量,一个是WildDemo<String> demo1,另一个是WildDemo<Integer> demo2,来保存对这两种类型的实例的引用。如果使用通配符,则可以这样写:

    // 使用通配符 '?'
            WildDemo<?> demo;
            
            demo = new WildDemo<Integer>();
            demo = new WildDemo<String>();


    但要注意的是, 通过使用类型通配符声明的名称所引用对象,无法对该对象添加信息,只能获取或移除该对象的信息。如下例:

    import java.util.*;
    
    public class WildDemo<T>
    {
        private T x;
        
        // 为x赋值
        public void setX(T x)
        {
            this.x = x;
        }
        // 读取x的值
        public T getX()
        {
            return x;
        }
        
        public static void main(String[] args)
        {
            WildDemo<Integer> obj = new WildDemo<Integer>();
            obj.setX(100);
            
            // 使用通配符 '?'
            WildDemo<?> demo = obj;
            demo.getX(); // 读取信息,OK
            demo.setX(null); // 移除信息,OK
            demo.setX(200); // 设置新的信息给X, ERROR
        }
    }



    3、泛型类的继承

    定义父泛型类:

    class Parent<T1,T2>{}

    定义子泛型类从Parent继承而来:

    class Child<T1,T2,T3> extends Parent<T1,T2>{}


    如果子类想保留父类的类型持有者T1,T2,那么父类上所声明的类型持有者的数目在继承下来时必须写全,即class Child<T1,T2)>。如果子类不保留类型持有者,那么继承下来的T1,T2自动变为Object类型。


    在实际应用中我们使用泛型应该本着简洁易读的原则来定义泛型类,要尽量避免定义有多重<>的复杂泛型。


  • 相关阅读:
    mac使用ssh出现permission denied(publickey)
    mac下解压bin文件
    Lint found fatal errors while assembling a release target问题的解决方案
    Cloud Foundry 组件
    maven中的groupId和artifactId到底指的是什么
    SpringBoot之常用注解
    Kafka系列文章
    [转]Kafka 设计与原理详解
    十张图了解Docker【转】
    四层、七层负载均衡的区别
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/2985366.html
Copyright © 2011-2022 走看看