Java的泛型小记

参考: http://www.oracle.com/technetwork/cn/articles/java/juneau-generics-2255374-zhs.html

是什么

场景:希望有一个容器,可以接受任意类型

基本实现

文档中首先提出了一种实现方式


public class ObjectContainer {
  private Object obj;

  public Object getObj() {
      return obj;
  }

  public void setObj(Object obj) {
      this.obj = obj;
  }
}

但是这种方式不是合适的解决方案。这种方式不是类型安全的,且要求在检索封装的对象的时候使用显示类型转换。这就有可能引发异常

使用泛型来处理这种问题


public class GenericContainer<T> {
    private T obj;

    public GenericContainer(){}         //无参构造

    public GenericContainer(T t){       //有参构造
        obj = t;
    }

    public T getObj(){
        return obj;
    }

    public void setObj(T t){
        obj = t;
    }
}

这时候,不确定的类型就不是Object了,而是T,这是泛型类型
如果我们创建了一个这类容器,且指定了类型,那么就不能再在里面存放别的类型的对象
这里的描述我更倾向于:https://segmentfault.com/a/1190000005179142里面的说法:
用一个类来包装一个变量,但是我们不确定变量类型的时候使用泛型。也称为[泛型类]。

使用泛型的好处

1.更强的类型检查。可以理解为因为指定了类型,就避免了其他类型的加入,避免发生类型转换错误
2.因为指定了类型,编译器明确知道集合中的数据类型,我们就可以直接使用对象调用其方法:意思就是说比如内部是String类型,我们就可以直接拿对象调用String的方法,无需再进行显示类型转换

如何使用泛型

上面的示例是生成泛型对象类型的用例
<T>是一个类型参数,表示在运行时,为这个类分配了这个类型,并且可以在整个类中使用
根据惯例,下面给出了常用的类型参数:

  • E:元素
  • K:键
  • N:数字
  • T:类型
  • V:值
  • S、U、V 等:多参数情况中的第 2、3、4 个类型

泛型可以用于构造函数的参数中,限制参数类型

如果一个类有多个类型参数,声明的时候,类型参数之间使用“,”分隔,如:


public class GenericContainer<T,S,E> {...}

这个就表示我这个类可以接收多个类型的参数

有界类型

情况是,我们希望控制类型参数的范围,而不是任何类型,常用方式就是在类型参数部分使用extends或super关键字,限制泛型类型的边界

比如:


//表示类型参数T属于Number的子类,指定了类型参数的上界
public class GenericNumberContainer <T extends Number>{...}

//这个我暂时没有找到例子,按照上面的理解就是这个泛型类型是T的父
//类,对应的,也就指定了类型参数的下界,至少也要是T的父类,待证
public class XXX<? super T>{...}

泛型方法

  1. 有时我们不知道方法将接受的类型,就可以在参数中使用泛型。
  2. 方法的返回类型也可以是泛型类型

在参数中使用泛型:

注意:我们要在返回值之前声明泛型类型,才能在参数中使用泛型类型


public <T> void getObj(T n){
        //...
    }

public static <N extends Number> double add(N a,N b){
        double sum =0;
        sum = a.doubleValue()+b.doubleValue();
        return sum;
    }

返回泛型类型

这里也需要在返回值之前声明泛型类型


public <T> T getObj(T n){
        return n;
    }

所以,我们在方法中需要使用到泛型的时候都要在返回值之前声明泛型类型

通配符

这里的通配符是指使用<?>来替代<T>
不推荐在返回值使用通配符,这样不安全

通配符一样可以使用extends或者super来限制上界和下界

小记:

泛型:

使用到某个类,处理类的方式是通用的,那么可以使用泛型。就行出租车拉乘客,为各种乘客提供服务,那么各种乘客就是泛型。不管是老人,小孩,男人,女人,出租提供的服务都是一样的

泛型擦除

在编译期间,所有的泛型都会转换为Object存在于字节码中,所以字节码中是没有泛型的类型信息的。比如你写的List<String>和List<User>到编译期,都是List<Object>

处理泛型擦除

需要手动进行类型转换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值