Java泛型详解


title: Java泛型详解
date: 2021-03-27 11:12:58
tags: 学习一下泛型吧!铁汁!


一篇博文

https://blog.csdn.net/s10461/article/details/53941091?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161726856216780262572785%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161726856216780262572785&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-53941091.first_rank_v2_pc_rank_v29&utm_term=java%E6%B3%9B%E5%9E%8B

泛型的概念

泛型,即“参数化类型”,顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。

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

为什么要使用泛型?

List arrayList = new ArrayList();
arrayList.add("aaaa");
arrayList.add(100);

for(int i = 0; i< arrayList.size();i++){
    String item = (String)arrayList.get(i);
    Log.d("泛型测试","item = " + item);
}

ArrayList可以存放任意类型,例子中添加了一个String类型,再使用时都以String的方式使用,因此程序崩溃了。为了解决类似的问题(就是在编译阶段就可以解决),泛型应运而生。

List<String> arrayList = new ArrayList<String>();
...
//arrayList.add(100); 在编译阶段,编译器就会报错

这样在编译阶段,程序就会报错!

为什么要使用泛型方法呢?因为泛型类要在实例化的时候就指明类型,如果想换一种类型,就不得不重新new一次,可能不够灵活;而泛型方法可以在调用的时候就指明类型,更加灵活。

怎么使用泛型?

泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法。

具体看:https://blog.csdn.net/s10461/article/details/53941091?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161726856216780262572785%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161726856216780262572785&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-53941091.first_rank_v2_pc_rank_v29&utm_term=java%E6%B3%9B%E5%9E%8B

泛型的注意点

1.泛型只在编译阶段有效。

在编译之后,程序会采取去泛型化的措施。泛型类型在逻辑上可以看成是多个不同的类型,实际上都是相同的基本类型

2.泛型的类型参数只能是类类型,不能是简单类型。

3.不能对确切的泛型类型使用instanceof操作。如下面的操作是非法的,编译时会出错。

Coffee<Breve> coffee = new Coffee<>();
//if语句括号里面的直接在编译阶段就报错了
        if (coffee instanceof Coffee<Breve>){
            System.out.println("true");
        }

4.同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。

5.’?‘泛型通配符是类型实参,而不是类型形参。什么意思?就是此处的?和Number、String、Integer一样都是一种实际的类型,可以把?看成所有类型的父类,是一种真实的类型。

6.泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型。

7.静态方法无法访问类上定义的泛型;如果静态方法操作的引用数据类型不确定的时候,必须将泛型定义在方法上。如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法。

8.为泛型添加上边界,即传入的类型实参必须是指定类型的子类型。

9.泛型的上下边界添加,必须与泛型的声明在一起。

10.不能创建一个确切的类型的数组,而使用通配符创建泛型数组是可以的。

11.数组的类型不可以是类型变量,除非是采用通配符的方式。因为对于通配符的方式,最后取出的数据是要做显式的类型转化

一个疑问

ArrayList<?extends Object> al = new ArrayList();

al.add(“aa”); //错

//因为集合具体对象中既可存储String,也可以存储Object的其他子类,所以添加具体的类型对象不合适,类型检查会出现安全问题。 ?extends Object 代表Object的子类型不确定,怎么能添加具体类型的对象呢?

public static void method(ArrayList<? extends Object> al) {
al.add(“abc”); //错

//只能对al集合中的元素调用Object类中的方法,具体子类型的方法都不能用,因为子类型不确定。

什么意思?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值