Java读书笔记-泛型(一)

本文为个人摘抄《Java 核心技术 卷I(第十版)》

Java 中的泛型

为什么要使用泛型程序设计?

泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象重用

在没有泛型的时候,泛型设计是怎么实现的?答案是使用继承

    public class ArrayList //before generic class
    {
        private Object[] elementData;
        ...
        public Object get(int i){...}
        public void add(Object o){...}
    }

对于使用这种方法,会出现两个问题:
1. 如果要获取一个值,必须进行强制类型转换(因为返回值是Object型)
2. 没有错误检查机制,可以添加任何类的对象(所有类都是Object型)
泛型提供了更好的解决方案:类型参数,如ArrayList就用类型参数来指示元素类型:

ArrayList<<String>> files=new ArrayList<String>();

使用类型参数的好处是
1. 使得代码具有更好的可读性
2. 使得编译器知道调用相应方法的时候的返回值类型,不需要用Object进行强制类型转换。
3. 编译器可以进行检查,避免插入错误类型的对象。

定义简单泛型类

一个泛型类就是具有一个或多个类型变量的类

public class Pair<T> //引入 类型变量T ,并用尖括号扩起,可以有多个泛型,用逗号隔开 如 <T,U>
{
   private T first; //成员变量为类定义中的变量类型
   private T second;

   public Pair() { first = null; second = null; }
   public Pair(T first, T second) { this.first = first;  this.second = second; }

   public T getFirst() { return first; } //方法返回类型为类定义中的变量类型
   public T getSecond() { return second; }

   public void setFirst(T newValue) { first = newValue; }//方法参数类型为类定义中的变量类型
   public void setSecond(T newValue) { second = newValue; }
}

注意:一般来说,类型变量使用大写形式,而且比较短
在Java 库中,使用变量E表示集合的元素类型,K,V表示关键值对、T、U、S表示任意类型

初始化时,用具体的类型变量替换类型变量的位置即可实例化

Pair<String>

除了泛型类以外,我们还可以在类中定义泛型方法

Class ArrayAlg
{
    Public staitc <T> T getMiddle(T…a) //类型变量放在修饰符后面 返回类型前
    {
        Return a[a.length/2];
    }
}

调用时在尖括号中放入具体类型

String middle=ArrayAlg.getMiddle("John","Q","Public");

几乎大多数泛型调用是没有问题的,但是还是会有情况会出错

Double middle =ArrayAlg.getMiddle(3.14,1729,0)

在这里编译器会自动打包参数为一个Double和2个Interger对象,然后寻找这些类的共同超类,而后找到Number和Comparable接口,但是本身他们也是泛型类型。
如果想要不出错,只能把参数全部改成double \让参数具有共同超类

类型变量 的限定
看到上面的例子,有时我们需要对类型变量进行一点小小的约束。比如下面计算数组最小元素的例子
public static T min(T[] a)
变量类型为泛型,意味着可以是任何一个类的对象,怎么样才能限定进入方法的变量具有compareTo方法呢?
那么,可以按照这样的方法对类型变量设置限定(bound)实现:

class ArrayAlg
{
  public static <T extend Comparable> T min(T[] a) 
  {
    if(a==null|| a.length==0)
     {
       return null;
     }
     T smallest=a[0];
     for(int i=0;i<a.length;i++)
     {
       if(smallest.compareTo(a[i])>0)
        {
          smallest=a[i];
        }
     }
     return smallest;
  }
}

这样如果没有实现Comparable的类调用就会产生编译错误
一个类型变量或者通配符可以有多个限定
例如

T extends Comparable &Serializable //限定类型用 "&" 分隔

在继承中,一个类只能继承一个类,但是可以实现多个接口,所以在泛型的限定中,至多有一个类,如果使用一个类作为限定,那么它必须是限定列表中的第一个。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值