夯实JAVA基本之一——泛型详解(2):高级进阶

前言:被温水煮惯了,梦想的东西总是不敢于尝试,失败了又怎样,最多从头来过。
 

 

 

相关文章:

1、《夯实JAVA基本之一 —— 泛型详解(1):基本使用》
2、《夯实JAVA基本之一——泛型详解(2):高级进阶》
3、《夯实JAVA基本之二 —— 反射(1):基本类周边信息获取》
4、《夯实JAVA基本之二 —— 反射(2):泛型相关周边信息获取》
5、《夯实JAVA基本之二 —— 反射(3):类内部信息获取》

 

 

上一篇给大家初步讲解了泛型变量的各种应用环境,这篇将更深入的讲解一下有关类型绑定,通配符方面的知识。

 

 

一、类型绑定

1、引入

我们重新看上篇写的一个泛型:

 

 

class Point<T> {
    private T x;       // 表示X坐标
    private T y;       // 表示Y坐标

    public void setX(T x) {
        this.x = x;
    }

    public void setY(T y) {
        this.y = y;
    }

    public T getX() {
        return this.x;
    }

    public T getY() {
        return this.y;
    }
}

//使用
Point<Integer> p1 = new Point<Integer>();
p1.setX(new Integer(100));
System.out.println(p1.getX());

首先,我们要知道一点,任何的泛型变量(比如这里的T)都是派生自Object,所以我们在填充泛型变量时,只能使用派生自Object的类,比如String,Integer,Double,等而不能使用原始的变量类型,比如int,double,float等。
然后,问题来了,那在泛型类Point<T>内部,利用泛型定义的变量T x能调用哪些函数呢?

private T x;  

当然只能调用Object所具有的函数,因为编译器根本不知道T具体是什么类型,只有在运行时,用户给什么类型,他才知道是什么类型。编译器唯一能确定的是,无论什么类型,都是派生自Object的,所以T肯定是Object的子类,所以T是可以调用Object的方法的。
那么问题又来了,如果我想写一个找到最小值的泛型类;由于不知道用户会传什么类型,所以要写一个接口,让用户实现这个接口来自已对比他所传递的类型的大小。
接口如下:

public interface Comparable<T>{
    public boolean compareTo(T i);
}

但如果我们直接利用T的实例来调用compareTo()函数的话,会报错,编译器截图如下:

 

这是因为,编译器根本无法得知T是继承自Comparable接口的函数。那怎么样才能让编译器知道,T是继承了Comparable接口的类型呢?
这就是类型绑定的作用了。

2、类型绑定:extends

(1)、定义
有时候,你会希望泛型类型只能是某一部分类型,比如操作数据的时候,你会希望是Number或其子类类型。这个想法其实就是给泛型参数添加一个界限。其定义形式为:

 

 

 

 

<T extends BoundingType>

此定义表示T应该是BoundingType的子类型(subtype)。T和BoundingType可以是类,也可以是接口。另外注意的是,此处的”extends“表示的子类型,不等同于继承。
一定要非常注意的是,这里的extends不是类继承里的那个extends!两个根本没有任何关联。在这里extends后的BoundingType可以是类,也可以是接口,意思是说,T是在BoundingType基础上创建的,具有BoundingType的功能。目测是JAVA的开发人员不想再引入一个关键字,所以用已有的extends来代替而已。
(2)、实例:绑定接口
同样,我们还使用上面对比大小的接口来做例子
首先,看加上extends限定后的min函数:

public interface Comparable<T> {
    public boolean compareTo(T i);
}
//添加上extends Comparable之后,就可以Comparable里的函数了
public static <T extends Comparable>  T min(T...a){
    T smallest = a[0];
    for(T item:a){
        if (smallest.compareTo(item)){
            smallest = item;
        }
    }
    return smallest;
}

这段代码的意思就是根据传进去的T类型数组a,然后调用其中item的compareTo()函数,跟每一项做对比,最终找到最小值。
从这段代码也可以看出,类型绑定有两个作用:1、对填充的泛型加以限定 2、使用泛型变量T时,可以使用BoundingType内部的函数。
这里有一点非常要注意的是,在这句中smallest.compareTo(item),smallest和item全部都是T类型的,也就是说,compareTo对比的是同一种类型。
然后我们实现一个派生自Comparable接口的类:

public class StringCompare implements Comparable<StringCompare> {
    private String mStr;

    public StringCompare(String string){
        this.mStr = string;
    }

    @Override
    public  boolean compareTo(StringCompare str) {
        if (mStr.length() > str.mStr.length()){
            return tr
  • 95
    点赞
  • 147
    收藏
    觉得还不错? 一键收藏
  • 30
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值