Java中泛型的使用

简介: 学Java的同学想必对泛型都不陌生,在日常工作中我们也经常会去和泛型打交道。我们对泛型可以说是既熟悉又陌生,熟悉的是我们每天都会写都会去使用它,但真正让我们去深入剖析,去解释泛型的用法,我们却又很难解释清楚,本文将带大家以最容易懂的方式去理解泛型,去剖析泛型。

泛型的解释

泛型: 泛型属于一种程序设计语言的的标准和规范,或者也可以说为特性。

通俗的解释泛型: 泛型其实就是我们参数化类型,就比如在定义List的时候,我们就可以写作List<String>这样我们就在编码阶段,将List存放的类型定义好。这样的话,我们在操作List的时候就可以通过泛型对我们集合内的值进行规范和约束,如果我们传入非法的类型时程序在编译阶段就能帮我们找出问题,就不会出现隐形的异常。

如下例子中,如果我们不通过泛型进行约束,写代码,运行代码的时候我们都是不知道会出错,只有当程序执行到这句话的时候才会抛出异常。

List list = new ArrayList();
list.add("abc");
list.add(100);
for(int i = 0; i< list.size();i++){
    System.out.println("执行到第 " + (i+1) + " 次循环。");
    String str = (String) list.get(i);
    System.out.println(str);
}

执行结果:

执行到第 1 次循环。
abc
执行到第 2 次循环。
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at com.zhj.business.test.Test01.main(Test01.java:18)

结果分析:可以看出程序完整的完成了第一次循环,是在第二次循环时才触发类型转换异常的。当项目很大的时候,像这样的细节是很容易被忽略的,所以我们通过泛型,约束类型,这样我们在提取数据保存是对应类型即可,不需要进行强转,就不会出现上诉问题。

泛型的特性

在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。

泛型信息是不会进入到运行时阶段。

总结: 泛型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。

泛型的用法

泛型共有三种使用方式,分别为:

  • 泛型类

    public class Result<T> implements Serializable {
    ​
        /**
         * 状态码
         */
        private Integer code;
    ​
        /**
         * 消息
         */
        private String msg;
    ​
        /**
         * 返回数据
         */
        private T data;
    ​
        public Result(Integer code, String msg, T data) {
            this.code = code;
            this.msg = msg;
            this.data = data;
        }
    }
  • 泛型接口

    List其实就是最典型的泛型接口

    public interface List<E> extends Collection<E> {
    ​
    }    
  • 泛型方法

    List 接口中的toArray()方法就是典型的泛型方法

    /**
     * 泛型方法的基本介绍
     * @param T[] 传入的泛型实参
     * @return T[] 返回值为T[]类型
     * 说明:
     *     1)public与返回值中间的<T>,可以理解为声明此方法为泛型方法。
     *     2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
     *     3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
     *     4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
     *     5)必须在权限声明public与返回值之间的<T>上添加上下边界,即在泛型声明的时候添加
     */
    public <T> T[] toArray(T[] a) {
        int size = size();
        if (a.length < size)
            return Arrays.copyOf(this.a, size,(Class<? extends T[]>) a.getClass());
        System.arraycopy(this.a, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

注意:

  • 泛型的类型参数只能是类类型,不能是简单类型。
  • 不能对确切的泛型类型使用instanceof操作。
  • 实现泛型接口时,未传入泛型实参时,在声明类的时候,需将泛型的声明也一起加到类中,List必须指定,不然会报错,如下示例

    public interface List extends Collection

  • 如果静态方法要使用泛型的话,无法访问泛型类型的参数,必须将静态方法也定义成泛型方法

    public static void show(T t)

  • 泛型可以指定边界<T extends Number> 泛型方法上指边界必须在权限声明与返回值之间的上添加
  • 泛型方法中权限声明与返回值之间的 ,还可以指定多个泛型<T,K>
  • 类型通配符一般是使用?代替具体的类型实参List<?> 通配符>代替的是String之类的实参。

泛型的灵活应用能够极大的加强程序的质量,大家可以积极的应用。

目录
相关文章
|
1天前
|
存储 Java 编译器
深入理解 Java 泛型和类型擦除
【4月更文挑战第19天】Java泛型是参数化类型,增强安全性与可读性,但存在类型擦除机制。类型擦除保证与旧版本兼容,优化性能,但也导致运行时无法访问泛型信息、类型匹配问题及数组创建限制。为应对这些问题,可使用Object类、instanceof运算符,或借助Guava库的TypeToken获取运行时类型信息。
|
1天前
|
JavaScript Java 编译器
Java包装类和泛型的知识点详解
Java包装类和泛型的知识点的深度理解
|
1天前
|
Java
java中的泛型类型擦除
java中的泛型类型擦除
14 2
|
1天前
|
安全 Java 程序员
Java 泛型
Java 泛型
14 0
|
1天前
|
安全 Java 编译器
java泛型浅谈
java泛型浅谈
6 1
|
1天前
|
存储 安全 Java
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
|
1天前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
【5月更文挑战第2天】JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
42 2
|
1天前
|
安全 Java 编译器
【JAVA】泛型和Object的区别
【JAVA】泛型和Object的区别
|
1天前
|
存储 算法 Java
滚雪球学Java(20):Java泛型与枚举:提升代码灵活性与可读性
【4月更文挑战第9天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
28 1
滚雪球学Java(20):Java泛型与枚举:提升代码灵活性与可读性
|
1天前
|
Java