泛型是什么?它在java中又有哪些必要性?(代码片段)

守夜人爱吃兔子 守夜人爱吃兔子     2022-11-29     737

关键词:

1、什么是泛型?

对于大部分同学而言,泛型一词并不陌生,因为在Java开发中经常会用。常用的List、Map都用到过,所以泛型在Java中的重要的地位不言而喻。同时泛型也被广泛应用于面向对象编程和各种设计模式中。那么究竟什么是泛型,我们又为什么要用泛型?

下面我们通过一道测试题来为同学们做解释:

List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();

System.out.println(l1.getClass() == l2.getClass());

上面输出的结果是什么?懂泛型的同学肯定知道答案,就是true,因为这是典型地泛型类型擦除。

泛型是Java5才有的。在此之前,Java中的对象集合,往往是需要转换为Object对象,取出对象也是要再次进行强制类型转换,这样的操作带来了ClassCastException风险。泛型的加入,使得集合在编译阶段就可以推断出集合中元素类型,减少了代码臃肿和异常风险。

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

2、泛型的使用

定义类、接口或方法时使用类型形参(泛型),在声明变量、创建对象、调用方法时候会动态指定这个泛型。

2.1 泛型类

public class Apple<T> 
    //使用T类型定义实例变量
    private T info;
    public Apple()
    //使用T类型来定义构造器
    public Apple(T info)
        this.info = info;
    
    public T getInfo() 
        return info;
    
    public void setInfo(T info) 
        this.info = info;
    

//使用
Apple<String> name = new Apple<>("苹果");
Apple<Double> price = new Apple<>(.);

泛型类与普通类的区别就是在方法名后使用进行了声明泛型形参,接下来可以在类中将T作为类型使用(如上面直接定义变量info)。

2.2 泛型接口

//泛型形参E
public interface loadResult<E>
    //E 作为参数类型
    void returnResult(E result);

public interface addResult<E>
    //E 作为类型使用
    E add();

泛型接口跟泛型类声明基本一样,使用的范围也是相同。

2.3 泛型方法

List不是List子类,如果想要将每一个String类型的数组元素放到一个集合中,集合的数据类型只能是String:

     String[] fruitArray = new String[]"apple","banana","peach";
     List<String> fruitList = new ArrayList<>();
     array2Collection(fruitArray,fruitList);
     Log.d(TAG,">>>>>> fruitList = " + fruitList);

    //代码省略...
    private void array2Collection(String[] array, List<Object> list) 
        for (String str : array) 
            list.add(str);
        
    

比如上面的代码,在编译环境下就会报异常。所以如果后期需要放置Integer类型,就需要再次新建Integer的集合,这样的方法功能十分有限。

为了解决这个问题,Java设计了泛型方法。泛型方法对比普通方法多了泛型形参声明,所有的泛型形参声明放在修饰符和方法返回值中间。

修饰符 <T,S> 返回值类型 方法名(形参列表)
    //方法体
private static <T> void add(T t) 
   Log.d(TAG, ">>>>>>" + t + "-100");

使用泛型方法来完成将数组数据元素放到集合中

//定义一个泛型方法,T泛型形参仅可以在该方法中使用
private <T> void array2Collection(T[] array, List<T> list) 
    for (T str : array) 
            list.add(str);
    

//泛型方法使用
String[] fruitArray = new String[]"apple", "banana", "peach";
List<String> fruitList = new ArrayList<>();
Integer[] integers = new Integer[]3;
Float[] floats = new Float[]1.0f, 2.0f, 3.2f;
List<Number> numberList = new ArrayList<>();
array2Collection(integers, numberList);
Log.d(TAG, ">>>>>> Integer[] numberList = " + numberList);
array2Collection(floats, numberList);
Log.d(TAG, ">>>>>> Float[] numberList = " + numberList);
array2Collection(fruitArray, fruitList);
Log.d(TAG, ">>>>>> List<String> fruitList = " + fruitList);

//输出结果:
D: >>>>>> Integer[] numberList = [3]
D: >>>>>> Float[] numberList = [1.2.3.2]
D: >>>>>> List<String> fruitList = [apple, banana, peach]

3、泛型通配符

除了用 <T>表示泛型外,我们还经常碰到 <?>这种形式的泛型, ? 被称为通配符。

通常通配符的出现是为了指定泛型中的类型范围。通配符简分为 3 种形式:被称作无限定的通配符、被称作有上限的通配符、被称作有下限的通配符。

3.1、无限定通配符

无限定通配符经常与容器类配合使用,它其中的 ? 其实代表的是未知类型,所以涉及到 ? 时的操作,一定与具体类型无关。

public static void showShapes(List<?> shapeList)  

<?>存在时,其实List 对象丧失了 add() 方法的功能,当调用时编译器不通过。

public static void showShapes(List<?> shapeList)  
    shapeList.add(new Circle());//报错 ? cannot applied to Circle

<?>提供了只读的功能,也就是它删减了增加具体类型元素的能力,只保留与具体类型无关的功能。它不管装载在这个容器内的元素是什么类型,它只关心元素的数量、容器是否为空。

3.2、上界通配符

上限通配符用于在方法中放宽对变量类型的限制。代表类型 T 及 T 的子类。

上面的方法改为:

public static void showShapes(List<? extends Shape> shapeList) 
     for (Shape shape:shapeList)
         Log.i(TAG,"shape="+shape.getShape());
     


showShapes(circleList);//可以运行
showShapes(triangleList);//可以运行

shapeList.add(null);//不报错
shapeList.add(new Circle());//报错 Shape cannot applied to Circle

可以对列表中的?对象进行操作了。但是,注意的是对于上界泛型列表,除空之外,我们不允许将任何对象添加到列表中。

3.3、下界通配符

上界泛型列表,无法添加对象,如果需要添加,可以用下界通配符实现。

public static void showShapes(List<? super Shape> shapeList) 
    shapeList.add(new Circle());
    shapeList.add(new Circle());

 最后

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

不用多说,相信大家都有一个共识:无论什么行业,最牛逼的人肯定是站在金字塔端的人。所以,想做一个牛逼的程序员,那么就要让自己站的更高,成为技术大牛并不是一朝一夕的事情,需要时间的沉淀和技术的积累。

现在竞争这么激烈,只有通过不断学习,提高自己,才能保持竞争力。

对于一些不知道学习什么,没有一个系统路线的程序员,这里给大家提供一些学习资料

需要的小伙伴,可以一键三连,点击这里获取免费领取方式

《Java核心知识点合集(283页)》

内容涵盖:Java基础、JVM、高并发、多线程、分布式、设计模式、Spring全家桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat、数据库、云计算等

《Java中高级核心知识点合集(524页)》

《Java高级架构知识点整理》

《Docker从入门到实践》

《spring could 学习笔记》

《JVM与性能调优知识点整理》

《MySQL性能调优与架构设计解析文档》305页

《Nginx入门到实战》319页

《Java并发编程》385页

《1000道 互联网Java工程师面试题 (485页)》

需要的小伙伴,可以一键三连,点击这里获取免费领取方式 

java泛型是什么?一文带你吃透泛型(代码片段)

文章目录1.Java泛型2.泛型类3.泛型接口4.泛型方法5.泛型集合Java编程基础教程系列1.Java泛型Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。其主要的形式有泛型类,泛型接口和泛型方法。泛型概... 查看详情

typescript中泛型是什么(代码片段)

在TypeScript中,泛型是一种创建可复用代码组件的工具。这种组件不只能被一种类型使用,而是能被多种类型复用。类似于参数的作用,泛型是一种用以增强类(classes)、类型(types)和接口(interfa... 查看详情

java泛型是假泛型,好烦这个东西

今天新来的小伙子让我帮忙看一个bug,在for遍历List时提示ClassCastException。伪代码 for(Orderorder:model.getOrderList)...debug之后发现OrderList里放的是Object[]数组,于是追到了注入的位置orderList=(ArrayList<OrderList>)query.list();这里强转失... 查看详情

java泛型了解嘛?(代码片段)

泛型是啥泛型:参数化类型具体一点类似于方法中的变量参数。泛型的本质就是参数化类型,操作的数据类型被指定为一个参数。同时,泛型是JDK5引入的新特性,泛型提供了编译时安全检测机制,允许在编译... 查看详情

赢在面试之java泛型篇

139.Java中的泛型是什么?使用泛型的好处是什么?        泛型是JavaSE1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。好处:        1... 查看详情

java泛型,你了解类型擦除吗?(代码片段)

泛型,一个孤独的守门者。大家可能会有疑问,我为什么叫做泛型是一个守门者。这其实是我个人的看法而已,我的意思是说泛型没有其看起来那么深不可测,它并不神秘与神奇。泛型是Java中一个很小巧的概念&#x... 查看详情

json反序列化泛型对象;泛型是变化的,如何写出通用代码?(源码分析)(代码片段)

...#xff0c;gson等其他序列化工具都类似。json如何反序列化出带泛型的结果,这个网上应该很多教程,但本文想要实现更高难度的反序列化。比如:泛型参数在变化,怎么写出通用代码?看例2先看使用一共三个类... 查看详情

javase语法基础---泛型(基础知识问答)

文章目录如果没有泛型?什么是泛型,介绍一下泛型?各个版本泛型的使用及变化说一下?泛型的意义?泛型的好处?1.Java中的泛型是什么?使用泛型的好处是什么?2.Java的泛型是如何工作的或者什么是类型... 查看详情

泛型-类型擦除

参考:java核心技术一、Java泛型的实现方法:类型擦除前面已经说了,Java的泛型是伪泛型。为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉。正确理解泛型概念的首要前提是理解类型擦出(typee... 查看详情

java泛型常问面试题总结(代码片段)

文章目录Java泛型常问问题1.Java中的泛型是什么?使用泛型的好处是什么?2.如何编写一个泛型方法,让它能接受泛型参数并返回泛型类型?3.下面能编译通过?4.Array中可以用泛型吗?5.编写Employee类6.你可以把`List`传递给... 查看详情

java泛型常问面试题总结(代码片段)

文章目录Java泛型常问问题1.Java中的泛型是什么?使用泛型的好处是什么?2.如何编写一个泛型方法,让它能接受泛型参数并返回泛型类型?3.下面能编译通过?4.Array中可以用泛型吗?5.编写Employee类6.你可以把`List`传递给... 查看详情

java泛型讲解

原文: https://blog.csdn.net/briblue/article/details/76736356泛型,一个孤独的守门者。大家可能会有疑问,我为什么叫做泛型是一个守门者。这其实是我个人的看法而已,我的意思是说泛型没有其看起来那么深不可测,它并不神秘与神... 查看详情

java-泛型-1(代码片段)

什么是泛型泛型是JavaSE1.5的特性,本质是参数化类型。用于区别于原生类型,作为限定传参,方法的类型等。并且类型明确的这种工作放到创建对象或者在调用方法的时候才去明确的具体类型的特殊类型。例如Listlist&... 查看详情

java-泛型-1(代码片段)

什么是泛型泛型是JavaSE1.5的特性,本质是参数化类型。用于区别于原生类型,作为限定传参,方法的类型等。并且类型明确的这种工作放到创建对象或者在调用方法的时候才去明确的具体类型的特殊类型。例如Listlist&... 查看详情

java重点--泛型(代码片段)

文章目录💖泛型的概念✨使用泛型的好处与弊端✨定义和使用含有泛型的类✨定义和使用含有泛型的方法✨定义和使用含有泛型的接口✨泛型的通配符✨通配符的高级使用--受限泛型✨斗地主小案例💖泛型的概念泛型是... 查看详情

深入理解java泛型

泛型是什么一说到泛型,大伙肯定不会陌生,我们代码里面有很多类似这样的语句:List<String>list=newArrayList<>();ArrayList就是个泛型类,我们通过设定不同的类型,可以往集合里面存储不同类型的数据类型(而且只能存储... 查看详情

java中的泛型---java编程思想

前言?我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的。通透理解泛型是学好基础里面中非常重要的。于是,我对《Java编程思想》这本书中泛... 查看详情

java泛型定义和基本使用笔记(代码片段)

1、泛型的作用以及定义1.概述 在我的理解中,泛型主要面向程序封装和架构设计的使用,在面向对象编程及各种设计模式中有非常广泛的应用。 为什么这么说呢,首先我们要理解什么是泛型,为什么要使用泛型&#... 查看详情