Java基础|| 泛型初了解

  • 泛型

    学习之初我本来想悄悄跳过这一节。愚蠢。人类真是愚蠢【我指我】。学集合不学泛型可能是背书背多了想把集合章节背下来理解吧。
    PS:我现在在看的以及大部分总结内容均来自Cay S.Horstmann著的《Java核心技术卷 1》

    聪明的朋友萌不要学我 跟着愚蠢的阿柳痛改前非8!

    1.简单来说:一个泛型类(generic class)就是具有一个或多个类型变量的类。
    例 Pair类:

public class Pair<T>
{
  private T first;
  private T second;
  
  public Pair(){ first=null; second=null; }
  public Pait(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){ seond=newValue; }
}

注1:泛型类可以有多个类型变量。例如 可以定义Pair类,其中第一个域和第二个域使用不同类型:
public class Pair<T,U>{ . . . }

注2:Java中用E表示集合的元素类型,K和V表示表的关键字(key)和值(value)的类型,T(或者U,S)表示任意类型。

使用泛型类的时候把<>内的T换成所需类型即可。

2.前面介绍了如何定义一个泛型类。下面来定义一个带有类型参数的简单方法。

class ArrayAlg
{
  public static <T> T getMiddle(T...a)
  {
    return a[a.length/2]; 
  }
}

注1:泛型方法既可以定义在普通类中,也可以定义在泛型类中。
注2:类型变量<T>放在修饰符(这里是public static)后,返回类型前。

调用此方法的时候可以:

String middle=ArrayAlg.<String>.getMiddle("Lucy","Bradly',"MengNiu");

注1:大多数情况下可以忽略<>内的类型(连同<>一起去掉),因为编译器可以推断出。比如推断出这里类型是String。

3.类型变量的限定
当我们定义的类或方法中出现了某些特定方法,比如compareTo()。这时候,要确保T所属的类含compareTo()方法。So我们需要对类型变量加以约束。
例:

public static <T extends Comparable>T min(T[] a)...

也可以有多个限定,例:

public static <T extends Comparable&Serializable>T min(T[] a)...

4.约束与局限
(1)不能创建参数化类型的数组,例:

Pair<String>[] table=new Pair<String>[10];//Error

为什么?
因为泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。只留下它的原始类型(如:Object)。
而数组擦除之后会记住它的元素类型,如果试图储存其他类型的元素,就会抛出ArrayStoreException异常。
(2)不能抛出或捕获泛型类的实例,事实上,甚至泛型类扩展Exception都是不合法的。例:

public class Problem<T> extends Exception {...}//Error:cannot extends Throwable

catch子句中同样也不能使用类型变量,例:

public static <T extends Throwable> void doWork(Class<T> t)
{
  try
  {
    *do work*
  }
  catch(T e)//Error:cannot catch type variable
  {
    Logger.global.info(...)
  }
}

不过,在异常规范中使用类型变量是允许的,例:

public static <T extends Throwable> void doWork(T t) throws T//OK
{
  try
  {
    *do work*
  }
  catch(Throwable realCause)
  {
    t.initCause(realCause);
    throw t;
  }
}

5.泛型类型的继承规则
考虑一个类和一个子类,如 Employee类和Manager类。Pair《Manager>是Pair《Employee>的一个子类吗?

不是。

无论S类和T类有什么关系,通常Pair《S>和Pair《T>没有什么联系。

6.通配符 ‘?’
啊 不想写了。自行百度。简单来说就是让父子类在泛型中有用武之地了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值