java 泛型的学习和理解

首先,我也是借鉴许多网上的资料来进行模仿和理解,便于以后的时候,主要的目的为了记录下,方便以后回看。

最近在看数据结构和算法分析java 版的时候,直接被习题给难住了,根本无从下手,所以决定重新认识和了解下泛型,查漏补缺。
这里写图片描述


1.什么是java 泛型

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

2.泛型的使用的限制

  • 泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
  • 同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
  • 泛型的类型参数可以有多个。
  • 泛型的参数类型可以使用extends语句,例如。习惯上称为“有界类型”
  • 泛型的参数类型还可以是通配符类型。例如Class

3.? E T 的含义后区别

遇到 T,E,K,V等,是用到了java中的泛型。
一般使用<#T#>来声明类型持有者名称,自定义泛型类时,类持有者名称可以使用T(Type)
如果是容器的元素可以使用E(Element),若键值匹配可以用K(Key)和V(Value)等,
若是 ?,则是默认是允许Object及其下的子类,也就是java的所有对象了。

所以说,如果是字每A,B,C,D…定义的,就是泛型,这里T只是名字上的意义而已
T—type,E—-Element
K—-key, V—-value
如果是?定义的,就是普通的Object或者其子类

举例说明: #号是多余的
Set<#T#> 表示 集合里 是 T类的实例
List<#E#> 表示 集合里 是 E类的实例
List<#?#> 表示 集合里的对象类型不确定,未指定
List 同 List<#?#> 是一样的。

4.代码说明

  • 4.1 这里是默认的使用Object 的例子
@/**
 * 通用类型的一个例子 on 2016/3/18.
 */
public class GenNormalDemo {
    private Object object;

    public GenNormalDemo(Object o){
        this.object = o;
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    public String showType(){
        return "实际参数的类型是="+object.getClass().getName();
    }

}

这里写图片描述

在解析的时候,需要进行类型的强制转换。

下面是使用泛型的例子:

/**
 * 使用泛型定义的类型 on 2016/3/18.
 */
public class GenTDemo<T> {
    private T object;

    public GenTDemo(T ob){
        this.object = ob;
    }

    public T getObject() {
        return object;
    }

    public void setObject(T object) {
        this.object = object;
    }

    public String showType(){
        return "泛型定义的类的实际参数的类型是="+object.getClass().getName();
    }
}

这里写图片描述

使用泛型的时候,直接获取的是相应的类型。不许强制转换。
注意:基本类型无法作为 T 的实际参数传递的

下面是对为什么能获取到对应类型的解释,为什么类没有受到类擦除机制的影响。(摘录)

第一组关键词:引用,实例化。

先看下面这个简单的例子:
Object obj=new Integer();
System.out.println(obj.getClass());

obj是引用,引用的类型是Object,实例的类型是Integer
我们知道,引用是栈保存的一个类似地址的信息,本身没有任何含义,真正能保存信息的是new Integer()所划分的内存空间。
即是说,Integer这个信息是在实例里的

第二组关键词:继承,父类,子类
Integer继承自Object
obj.getClass()调用的是Integer的getClass方法,当然Integer是没有该方法,于是一直回溯到父类Object,找到Object的getClass方法,实现是本地native方法,我们不知道内部怎么构造,但是可以肯定,它是在根据引用地址找到实例位置,确定实例类型。
综合第一组可知,在这里,实例类型是Integer

第三才是泛型。
其实在第一部里面已经说明过了。
GenTDemo并没有维护T的信息。
维护T信息的是T ob;
GenTDemo<#Integer#> iObject执行这一部的时候,ob就认为自己是个Integer类型了。当它具有了实例之后,你才能调用getClass方法
所以综合上两点才表现出了你看到的效果。

对于GenTDemo来说,一旦运行,它就不在乎T是什么类型了,但是ob需要知道自己的类型吧?这个Integer被维护在了实例里。

  • 4.2 泛型的限制,可以向上限制也可以向下限制
/**
 * 泛型里面的 T extends 的含义包括了 原来的 继承和实现,是两者的结合
 * T 必须是集合的类
 * lh on 2016/3/18.
 */
public class CollectionGenFoo< T extends Collection> {
/**
 * lh on 2016/3/18.
 * 其中? 通配符泛型 表示不确定的类型
 * 其中k  表示内部实现comparable 的类,类似String,int 等
 */
public class Gen2Value<T,K extends Comparable<?>> {
    private T t;
    private K k;

    public Gen2Value(T t1,K k1){
        this.t = t1;
        this.k = k1;
    }
/**
 * lh on 2016/3/18.
 * 其中? 通配符泛型 表示不确定的类型
 * 其中k  表示内部实现comparable 的类,类似String,int 等,? super Double  而且必须是Double的父类
 *
 */
public class GenSuper2Value<T,K extends Comparable<? super Double>> {
    private T t;
    private K k;

    public GenSuper2Value(T t1, K k1){
        this.t = t1;
        this.k = k1;
    }

下面截图中都有解释说明
这里写图片描述

4.3 泛型的方法的使用

使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。
需要注意,一个static方法,无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。

/**
 * lh on 2016/3/18.
 */
public class TMethoddemo {

    public <T> void f(T x){
        Log.d("test","测试泛型方法 TMethoddemo x="+x.getClass().getName());
    }

}

这里写图片描述

最后

对于开头提出的问题,现在有点思路,还是希望有人帮助当然最好。。。。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值