文档章节

小论Java泛型机制

SamYjy
 SamYjy
发布于 11/15 14:49
字数 872
阅读 9
收藏 0

何为泛型(Generics)

面向对象编程语言的多态特性包括:任一多态(ad hoc polymorphism,又名重载)、子类型多态(subtype polymorphism,又名覆盖)以及参数多态(parameter polymorphism,也即泛型)三种特性。泛型指的是程序语句编写时不考虑变量参数类型,或程序的设计与具体才用何种类型的变量无关,而在运行时决定参数类型的程序编写方式。

在较为高级成熟的编程语言中,泛型编程是程序语言自带的特性。比如在Python或Visual Basic中,声明变量时不需要声明变量的类型。Java 是从Java 5开始支持对类进行泛型编程的。

非泛型编程造成的问题

Java 5之前,当程序中需要设置与类型无关的变量时,只能采用Object变量。下面就是一个典型的Java 5之前的程序:

public class WeakPair {
    private final Object first;
    private final Object second;

    public WeakPair(Object first, Object second){
        this.first = first;
        this.second = second;
    }

    public Object getFirst(){  return first;}
    public Object getSecond(){  return second;}

    public String toString(){
        return "(" + first.toString() + "," + second.toString() + ")";
    }

}

这样的程序有如下一些问题:

  1. 其调用程序的变量需要经过强制转换才能编译。
  2. 由于变量类型错误导致的程序问题不能在编译时被发现,而需要等到程序运行时才能发现。比如,如下的代码便会在运行时报TypeError异常:
WeakPair p2 = new WeakPair("Everything", 42);
int i2 = (int) p2.getFirst();

而采用泛型编程,调用程序的变量就不需要经过强制转化了,而且调用程序变量的类型错误能在编译时就被发现。比如,若将WeakPair改成泛型类之后,其调用示例如下:

如上图,程序中不符合泛型参数的调用在netbeans中就会被加上下划线。那么,这样的泛型类或泛型方法如何书写呢?

编写泛型类

Java中泛型的书写,即在类名后加上“<>”,然后再在“<>”中声明代表类型的参数即可。该参数一般采用一个大写字母,用E(entity)、T(type)、或K-V(用于类型中有键值对的情形),以下就是Pair对的泛型类书写方式。

public class Pair<T1, T2> {
    private final T1 first;
    private final T2 second;

    /**
     * 
     * @param first
     * @param second
     */
    public Pair(T1 first, T2 second){
        this.first = first;
        this.second = second;
    }

    public T1 getFirst(){  return first; }
    public T2 getSecond(){  return second; }

    public String toString(){
        return "(" + first.toString() + "," + second.toString() + ")";
    }
}

以下为它的一个调用方式:

        Pair<Integer, String> p1 = new Pair<>(i, "Everything");
        Pair<String, Integer> p2 = new Pair("Everything", 42);
        //正确的调用
        String s1 = p1.getSecond();
        int i1 = p1.getFirst();

编写泛型函数

泛型还可以用于某一函数中,而类中的其他函数不是泛型的情况。以下是一个获取一个数组中所有元素的真子集的函数:

/*
 * @author Dr.Thomas Christy, orginally created by:
 * @author Peter Schachte <schachte@unimelb.edu.au>
 * /
 public static <T> T[][] combinations(T[] list) {
        T[][] combos = (T[][])Array.newInstance(list.getClass(),
                (int) Math.pow(2, list.length));

        for (int i = 0 ; i < combos.length ; ++i) {
            int count = 0;
            for (int j = 0 ; j < list.length ; ++j) {
                if ((i & 1<<j) != 0) ++count;
            }
            combos[i] = (T[])Array.newInstance(list.getClass().getComponentType(), count);
            count = 0;
            for (int j = 0 ; j < list.length ; ++j) {
                if ((i & 1<<j) != 0) {
                    combos[i][count] = list[j];
                    ++count;
                }
            }
        }
        return combos;
    }

参考资料:

  1. W. Savitch, Absolute Java. Pearson Addison Wesley 6th Edition, 2013.
  2. T. Christy, Unimelb COMP90041 Programming and Software Development, 2018

© 著作权归作者所有

共有 人打赏支持
SamYjy

SamYjy

粉丝 60
博文 55
码字总数 101820
作品 0
其它
程序员
私信 提问
Java语言学习(十一):枚举类型和泛型

Java中一个重要的类型:枚举,它可以用来表示一组取值范围固定的变量,使用 enum 关键字定义枚举类型,其中元素不能重复,通常大写表示。利用Java的反射机制,可以在运行时分析类,如查看枚举...

海岸线的曙光
07/18
0
0
Java编程学习之泛型方法的了解 java开发

Java泛型方法和泛型类支持程序员使用一个方法指定一组相关方法,或者使用一个类指定一组相关的类型。 Java泛型是JDK 5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序...

老男孩Linux培训
05/29
0
0
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
06/21
0
0
Kotlin 泛型 VS Java 泛型

建议先阅读我的上一篇文章 -- Java 泛型 和 Java 泛型一样,Kotlin 泛型也是 Kotlin 语言中较难理解的一个部分。Kotlin 泛型的本质也是参数化类型,并且提供了编译时强类型检查,实际上也是伪...

JohnnyShieh
06/11
0
0
提给程序员和开发者的 10 道 Java 泛型面试题

关于泛型的面试题在 Java面试中变得越来越常见,因为 Java 5问世已经有相当长的时间了,越来越多的应用已经迁移到Java 5上来了,并且几乎所有新的Java开发工作也都是在Tiger(Java 5的项目代号...

lwei
2013/10/18
13.2K
30

没有更多内容

加载失败,请刷新页面

加载更多

Pure-ftpd搭建FTP

12月11日任务 15.4 xshell使用xftp传输文件 15.5 使用pure-ftpd搭建ftp服务 使用pure-ftpd搭建FTP服务 轻量的ftp软件 安装pure-ftpd并修改配置文件 # pure-ftpd为epel扩展库里的软件[root...

robertt15
14分钟前
2
0
开源 serverless 产品原理剖析(二) - Fission

背景 本文是开源 serverless 产品原理剖析系列文章的第二篇,关于 serverless 背景知识的介绍可参考文章开源 serverless 产品原理剖析(一) - Kubeless,这里不再赘述。 Fission 简介 Fiss...

阿里云官方博客
21分钟前
1
0
Android面试整理(附答案)

面试,无非都是问上面这些问题(挺多的 - -!),聘请中高级的安卓开发会往深的去问,并且会问一延伸二。以下我先提出几点重点,是面试官基本必问的问题,请一定要去了解! 基础知识 – 四大组...

终端研发部
25分钟前
3
0
Vue 改变数组触发视图更新

Vue 改变数组触发视图更新 以下方法调用会改变原始数组 push(), pop(), shift(), unshift(), splice(), sort(), reverse()push()push() 方法可向数组的末尾添加一个或多个元素,并返回新的...

不负好时光
31分钟前
2
0
计算机系统要素 C5

本章值得一提的是组织计算机的结构。Hack 的指令和数据是分开存储的,因此它的 CPU 有两个 input: IN inM[16], // M value input (M = contents of RAM[A]) instruction[16],...

lionets
47分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部