Java进阶:【泛型】认识泛型,泛型方法,泛型类,泛型接口和通配符

泛型

什么是泛型:

泛型就相当于标签

形式:<>

jdk1.5之后,用泛型来解决元素类型不确定的数据保存操作,

例如关于这个元素如何保存,如何管理等是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型。

没有泛型的集合

    public static void main(String[] args) {
        ArrayList al = new ArrayList();
        al.add(98);
        al.add(18);
        al.add(38);
        al.add(88);
        al.add("丽丽");
        for (Object o : al) {
            System.out.print(o+" ");
        }
    }

如果不使用泛型的话,有缺点:

一般我们在使用的时候基本上往集合里随意放值,因为底层是一个obj类型的数组,所以什么都能放,不方便管理。

在jdk1.5以后开始,使用泛型加入泛型的优点:在编译的时候就会对类型进行检查,不是泛型的就无法添加到这个集合

    public static void main(String[] args) {
        ArrayList<Integer> al = new ArrayList();
        al.add(98);
        al.add(18);
        al.add(38);
        al.add(88);
        for (Integer o : al) {
            System.out.print(o+" ");
        }
    }

总结:

  1. JDK1.5之后

  2. 泛型实际就是一个<>引起来的参数类型,这个参数类型具体在使用的时候才会确定类型

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-69skjX0R-1637915379643)(javaSE.assets/image-20210702134714327.png)]

  3. 使用了泛型后,可以确定集合的类型,在编译的时候就可以检查出来

  4. 使用泛型可能觉得麻烦,实际上使用泛型才会简单,后续的便利操作会简单许多

  5. 泛型对应的类型都是引用类型不能是基本类型

泛型类和泛型接口

声明泛型类时传入类型实参
创建泛型类对象时,传入类型实参
类型实参为空时,默认为Object类型

继承泛型类:

1.泛型父类不传入类型实参,默认为Object类型
2.泛型父类传入类型实参,子类既可以是泛型类,也可以不是
3.泛型父类传入类型实参,则子类必须是泛型类,且子类的类型形参列表必须包含父类的类型形参列表

泛型类的定义和实例化,如果实例化的时候不明确指定泛型,那么默认为Object类型

package TestGeneric.GenericTest;


public class test01<e> {
/*
* 这是一个普通类
* test01<a>就是一个泛型类
* <>里面就是一个参数类型,但是这个类型是什么?,不确定,相当于一个占位
* 但是现在确定的是这个类型一定是引用类型,而不是基本类型
* */
int age;
String name;
e sex;
public void a(e n){

}
public void b(e[] n){

}
static class Test{
    public static void main(String[] args) {
    test01 gt1 = new test01();
    gt1.a("abc");
    gt1.a(17);
    gt1.a(9.8);
    gt1.b(new String[]{"a","b","A"});

        test01<String> gt2 = new test01<>();
        gt2.sex ="男";
        gt2.a("abc");
        gt2.b(new String[]{"a","b","A"});
    }

}
}

继承:父类指定泛型接口

当父类指定了泛型类型,子类就不许要再指定了,可以直接使用

static class SubGeneric extends test01<Integer>{

}

static class Demo{
    public static void main(String[] args) {
            SubGeneric sgt = new SubGeneric();
                sgt.a(19);
    }
}
继承:父类不指定

如果父类不指定泛型,那么子类在实例化的时候需要指定

    static class SubGeneric2<e> extends test01<e>{
            
    }

泛型类可以定义多个参数类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i2nfeeEq-1637915379645)(javaSE.assets/image-20210702165119122.png)]

泛型类的构造器写法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPCg9z2z-1637915379646)(javaSE.assets/image-20210702165350108.png)]

不同泛型的引用类型不可以互相赋值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v9cLaZ0S-1637915379647)(javaSE.assets/image-20210702165519987.png)]

泛型如果不指定,就会被擦除,例子就是

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cKGuvmKC-1637915379648)(javaSE.assets/image-20210702165718451.png)]

泛型类中的静态方法不能使用类的泛型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RtjgLESS-1637915379649)(javaSE.assets/image-20210702165855642.png)]

不能直接使用泛型数组的创建,如果非要创建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6gumPZ00-1637915379650)(javaSE.assets/image-20210702170035488.png)]

泛型方法

  1. 什么是泛型方法,不是带泛型的方法就是泛型方法,泛型方法有要求:这个方法的泛型参数类型要和当前类的泛型方法的泛型无关
  2. 换个角度:泛型方法对应的那个泛型参数类型和当前所在的这个类,是否为泛型类,泛型是啥,无关
  3. 泛型方法定义的时候,前面要加上t,原因如果不加的话,会把t当作一种数据类型,然而代码中没有t类型那么就会报错
  4. t的类型实在调用方法的时候确定的
  5. 泛型方法是否是静态方法?可以是

代码类型:

public class test02<e> {
    public  void a(e e){

    }
    public static <T>  void b(T t){

    }

static class Demo{
    public static void main(String[] args) {
        test02<String> t2 = new test02();
        t2.a("1");
        t2.b("abc");
    }
}

泛型参数存在继承的情况

前面两个引用类型,都可以赋值,为什么list不行?

其实我们用的Arraylist,他的底层是一个Obj类型的数组,我们的泛型负责在编译的时候限制类型,

例子:两个类,a,b两类,a是b的父类,两者是继承关系,但是 G ,G两者不存在继承关系,应为他们都是引用Arraylist所以是同级关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QYnjGZ3k-1637915379651)(javaSE.assets/image-20210702170641900.png)]

通配符

当我想要重载不同泛型的list时,常见的重载无法让我们完成需求,于是我们需要通配符

在没有通配符的情况下,下面a方法,相当于重复定义

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nWXtToqT-1637915379652)(javaSE.assets/image-20210702171702364.png)]

通配符是什么?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6eEPiIFP-1637915379653)(javaSE.assets/image-20210702172150239.png)]

发现:两个类,a,b两类,a是b的父类,两者是继承关系,但是 G< a> ,G< b>两者不存在继承关系,应为他们都是引用Arraylist所以是同级关系但是使用了通配符后,我们发现G<?>变成了G< a> ,G< b>的父类

使用通配符

无边界通配符( ?),固定上边界通配符(?extends 上界类),固定下边界通配符(?super 下界类)

学习主要就是为了方便查看API文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YXa7qMy5-1637915379653)(javaSE.assets/image-20210702172437449.png)]

使用小细节

public  void  a(List<?> list){
//    遍历
    for (Object o : list) {
        System.out.println(o);
    }

//    数据的写入操作
//    list.add("abc");--》出错,不能随意的写入

//    读取操作
    Object s  = list.get(0);
}

泛型受限

并列关系,我们如何限制类型,

  • 用extends的是本类和类所有的子类:定义上限
  • 用super是本类和本类的父类,定义下限

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gi310NEx-1637915379654)(javaSE.assets/image-20210703082731875.png)]

        List<Object> a = new ArrayList<>();
        List<Person> b = new ArrayList<>();
        List<Student> c = new ArrayList<>();

A,B,C三个泛型的类型不相同,Person是Student的父类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷环渊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值