什么是泛型?泛型的基本原理与使用优势。

泛型使用到原理 为什么要有泛型 所谓泛型,就是类型参数化,也就是说,数据的类型不是固定的String,Integer,而是作为参数传入的。比如: // String就是参数,是List构造函数的参数。 List<String> list = new ArrayList<>(); 我们来看个更简单的例子: 现在有个需求,需要一个类,可以将任意String前面加上"Hello",后面加上"Android",然后能返回内容本身。我们实现如下: public class WrapperSt 阅读详情

目录

 

1. 什么是泛型?

2. 先来看一个简单的泛型例子

3. 那么T是什么呢?

4. 如何使用泛型,并将类型作为参数传入呢?

5. 泛型的基本原理

6. 使用泛型的好处


1. 什么是泛型?

泛型将接口的概念进一步延伸,“泛型”的字面意思就是广泛的类型。类、接口和方法代码可以应用于非常广泛的类型,代码与它们能够操作的数据类型不再绑定在一起,同一套代码可以用于多种数据类型,这样不仅可以复用代码,降低耦合性,而且还提高了代码的可读性以及安全性。讲起来优点抽象,我们看个实际的例子。

2. 先来看一个简单的泛型例子

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:14
 */

public class Pair<T> {
    T one;
    T two;

    public Pair(T one, T two) {
        this.one = one;
        this.two = two;
    }

    public T getOne() {
        return one;
    }

    public T getTwo() {
        return two;
    }
}

观察和普通类的区别:

  1. 类名后面多了一个<T>
  2. one 和 two的类型都是T

3. 那么T是什么呢?

T 表示类型参数

泛型就是类型参数化,处理的数据类型不是固定的,而是可以作为参数传入。

现在我们知道了,泛型把类型作为了参数来使用。

4. 如何使用泛型,并将类型作为参数传入呢?

如下代码:我们分别new了三Pair对象,其中传入了不同类型的类型参数(Integer、Character、String)。

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:22
 */

public class Test {
    public static void main(String[] args) {
        
        Pair<Integer> pairInteger =  new Pair<Integer>(1,2);
        int one1 = pairInteger.getOne();
        int two1 = pairInteger.getTwo();
        System.out.println("one:"+one1+",two:"+two1);

        Pair<Character> pairCharacter  =  new Pair<Character>('一','二');
        char one2 = pairCharacter.getOne();
        char two2 = pairCharacter.getTwo();
        System.out.println("one:"+one2+",two:"+two2);

        Pair<String> pairString  =  new Pair<String>("I","II");
        String one3 = pairString.getOne();
        String two3 = pairString.getTwo();
        System.out.println("one:"+one3+",two:"+two3);
    }
}

结果如下:

one:1,two:2
one:一,two:二
one:I,two:II

当然我们不仅可以传入一个类型参数,也可以传入多个类型参数。多个类型参数之间用 逗号“,”隔开。如下面的例子:

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:37
 */

public class PairTwo <U,V> {
    U one;
    V two;

    public PairTwo(U one, V two) {
        this.one = one;
        this.two = two;
    }

    public U getOne() {
        return one;
    }

    public V getTwo() {
        return two;
    }
}

可以这么使用:

PairTwo<String,Integer> pairTwo = new PairTwo<>("牛牛",20);

注意:自 Java 7 开始,支持省略后面的类型参数,让书写更简单些。

5. 泛型的基本原理

泛型类型参数到底是什么?为什么一定要定义类型参数呢?定义普通类,直接使用Object也是可以呀。如之前的Pair类我们可以写成:

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:44
 */

public class PairObject {
    Object one;
    Object two;

    public PairObject(Object one, Object two) {
        this.one = one;
        this.two = two;
    }

    public Object getOne() {
        return one;
    }

    public Object getTwo() {
        return two;
    }
}

然后这样使用,也是同样的效果:

package genericity.demo;

/**
 * @author BastetCat
 * @data 2019/8/8 21:46
 */

public class TestPairObject {
    public static void main(String[] args) {
        PairObject pairObject1 = new PairObject(1,2);
        int one1 =(int)pairObject1.getOne();
        int two1 =(int)pairObject1.getTwo();
        System.out.println("one:"+one1+",two:"+two1);

        PairObject pairObject2 = new PairObject("yi","er");
        String one2 =(String)pairObject2.getOne();
        String two2 =(String)pairObject2.getTwo();
        System.out.println("one:"+one2+",two:"+two2);
    }
}

输出结果:

one:1,two:2
one:yi,two:er

我们可以看到,确确实实我们的使用Object + 强制类型转换也实现了相同的结果。事实上,我们Java泛型的内部原理就是这样的。

我们使用JAD工具来反编译我们的Pair.class 与 Test.class得到的结果如下:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Pair.java

package genericity.demo;
public class Pair
{
    public Pair(Object obj, Object obj1)
    {
        one = obj;
        two = obj1;
    }
    public Object getOne()
    {
        return one;
    }
    public Object getTwo()
    {
        return two;
    }
    Object one;
    Object two;
}




// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Test.java

package genericity.demo;
import java.io.PrintStream;
// Referenced classes of package genericity.demo:
//            Pair

public class Test
{
    public Test()
    {
    }
    public static void main(String args[])
    {
        Pair pair = new Pair(Integer.valueOf(1), Integer.valueOf(2));
        int i = ((Integer)pair.getOne()).intValue();
        int j = ((Integer)pair.getTwo()).intValue();
        System.out.println((new StringBuilder()).append("one:").append(i).append(",two:").append(j).toString());
        Pair pair1 = new Pair(Character.valueOf('\u4E00'), Character.valueOf('\u4E8C'));
        char c = ((Character)pair1.getOne()).charValue();
        char c1 = ((Character)pair1.getTwo()).charValue();
        System.out.println((new StringBuilder()).append("one:").append(c).append(",two:").append(c1).toString());
        Pair pair2 = new Pair("I", "II");
        String s = (String)pair2.getOne();
        String s1 = (String)pair2.getTwo();
        System.out.println((new StringBuilder()).append("one:").append(s).append(",two:").append(s1).toString());
    }
}

通过以上的分析:

我们可以得知,Java的编译器将java源文件编译成字节码.class文件,虚拟机加载并运行。对于泛型类,java编译器会将其转换为普通的非泛型代码。将类型T擦除,然后替换为Object,插入必要的强制类型转换。Java虚拟机实际执行的时候,并不知道泛型这回事,只知道普通的类及代码。

那么为什么泛型要这样设计呢?

因为泛型是 Java 5 以后才支持的,这么设计是为了兼容性,而不得已的一个选择。

6. 使用泛型的好处

  • 代码复用:我们一套代码可以支持不同的类性。
  • 降低了耦合性:代码逻辑和数据类型之间分离,实现了解耦。
  • 更好的可读性:我们在使用集合的时候,定义了一个list 如List<String>,一看便知道这个一个存放String类型的list。
  • 更高的安全性:语言和程序设计的一个重要目标就是将bug消灭在摇篮里,能在写的时候消灭,就不要留在运行的时候。如我们定义一个List<String>这样的一个list。当我们往list里面放其他非String类型的数据时,我们的IDE(如Eclipse)就会报错提示。就算没有IDE。编译时,Java编译器也会提示,这称之为类型安全。这样就为程序设置了一道安全防护。同样的,使用泛型还可以省去使用普通对象时繁琐的强制类型转换。相反,使用普通对象,编译时并不会提示。假如传入的参数类型和最后强制类型转换的类型不一致。运行时就会出现ClassCastException,使用泛型则不会。
python调用hypermesh调用tcl_TclTk如何调用HyperMesh运行tcl脚本文件 #Tcl/Tk编写界面部分set t [toplevel .tp]focus $tgrab $tset Filename "E:/CAE_Tech/process_files/88/Example.tcl"set Font "Times 12 bold"wm title $t "Call HyperMesh"wm attribute $t -topmost 1wm withdraw $tset t... 阅读详情

相关推荐

避开奸商套路!手把手教你用Thaiphoon Burner和CPU-Z,一眼看穿内存SPD信息有没有被篡改

本文教你使用Thaiphoon Burner和CPU-Z工具,快速识别内存SPD信息是否被篡改,避免购买到虚标频率或假冒颗粒的内存条。通过详细步骤和实战案例,帮助用户掌握内存检测技巧,确保硬件购买的透明度和安全性。

weixin_32228501的博客 679

泛型的介绍以及原理

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

cj_eryue的博客 2134

HDMI协议介绍(二)--DataIsland Packets

前文简单介绍了HDMI传输的三个周期:控制周期、DataIsland周期和Video周期。DataIsland传输音频和辅助数据,这些数据以Packet的形式传输。本文简单介绍DataIsland Packet。

SlamDunk的博客 5671

什么是泛型?

泛型:就是指在类定义时不会设置类中的属性或方法参数的具体类型,而是在类使用时(创建对象)再进行类型的定义。会在编译期检查类型是否错误。

m0_49991895的博客 3万+

win10任务栏文件夹设置成竖形列表样式

win10任务栏文件夹设置成竖形列表样式

ftzchina的博客 7075

3D缺陷检测实战:从点云处理到工业质检优化

本文深入探讨了3D缺陷检测在工业质检中的实战应用,详细阐述了从点云处理到深度学习模型部署的完整技术链路。文章通过PCB焊点检测等实际案例,分析了3D视觉相比2D检测在识别深度、形状等缺陷方面的优势,并分享了点云滤波、分割、特征提取以及利用YOLOv5等模型进行高效检测的优化心得与落地挑战。

weixin_28358083的博客 336

浅谈泛型原理

Java中的泛型是什么 ? 泛型是JDK1.5的一个新特性,**泛型就是将类型参数化,其在编译时才确定具体的参数。**这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 使用泛型的好处是什么? 远在JDK 1.4版本的时候,那时候是没有泛型的概念的,如果使用Object来实现通用、不同类型的处理,有这么两个缺点: 每次使用时都需要强制转换成想要的类型 在编译时编译器并不知道类型转换是否正常,运行时才知道,不安全。 如这个例子: List list = ...

weixin_45712075的博客 958

DeerFlow 系列教程 附录 | 核心文件索引、官方文档索引与推荐阅读顺序

DeerFlow 系列教程 附录本附录汇集了 DeerFlow 项目的核心文件索引、官方文档索引和推荐阅读顺序三份速查资料,方便读者在日常开发和学习中快速定位关键代码与文档。内容按实际项目目录结构整理,所有路径均基于 DeerFlow 2.0 版本验证。

weixin_43674738的博客 327

java--基础--11.2--泛型--原理

案例//先检查:用String类型验证123,编译错误,如果要编译成功的话,下面代码可用反射//编译错误在上面的程序中,使用add方法添加一个整形,在eclipse中,直接就会报错,说明这就是在编译之前的检查。因为如果是在编译之后检查,类型擦除后,原始类型为Object,是应该运行任意引用类型的添加的。可实际上却不是这样,这恰恰说明了关于泛型变量的使用,是会在编译之前检查的。

zhou920786312的博客 463

AI自瞄原理剖析(四)从Yolo推理坐标到屏幕坐标:基于FOV视角与焦距的坐标变换与精准瞄准

从Yolo推理框架得到的坐标到屏幕坐标的转换是一个涉及到FOV视角、焦距以及分辨率的复杂过程。通过数学公式,我们可以将推理框坐标反推为游戏内的实际坐标,并最终映射到屏幕坐标系中。利用这些信息,AI自瞄系统能够精确计算出准星从当前位置移动到敌人位置的距离,实现精准的自动瞄准。通过这种方法,AI自瞄系统能够在不同的游戏环境下灵活应对,提供高度精确的操作体验。在AI自瞄系统中,目标检测仅仅是第一步,获取到预测框的坐标后,我们还需要将这些坐标转换为实际屏幕上的精确位置。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1332

全志T527-TP9930-Camera

TP9930 驱动模块主要实现将 4 路的 AHD/TVI/CVBS Camera 的数据转换为 BT656/BT1120 数据,从而实现在 T527 端来对数据进行处理和送显。

Linux驱动开发工程师,熟悉Linux/Android底层驱动、TP、显示、IIC、网络等通用外设调试适配,Linux上层应用开发。常用平台瑞芯微、全志、恩智浦等。 3232

泛型

泛型没有泛型之前有以下两个问题:l  从聚集(collection)中取出一个元素,必须把这个元素转换为具体类型。l  插入元素时,编译器不检查你插入的对象的类型与聚集中元素的类型是否相同。泛型的作用就是告诉编译器你希望聚集中的元素是什么类型,这样编译器就可以在编译阶段帮你检查你准备插入聚集的元素类型是否正确;或从聚集中取出元素时元素不需要强制转换,因为编译器已经知道聚集中的元素类型。泛型定义所谓

清箫的专栏 2632

Hermes 教程 03:Skills 系统

摘要:Hermes Skills是一种自我改进机制,可将解决问题的经验保存为可复用技能文档。v0.13.0版本遵循agentskills.io开放标准,与Claude Skills互通。技能创建流程包括发现问题、创建技能文件、加载使用和优化更新四个阶段。系统提供技能检索和自维护机制(Curator),支持技能媒体路由和多种管理命令。内置技能涵盖开发调试、创意头脑风暴等场景,通过积累技能使Hermes更适应用户需求。

程序猿_三产 725

泛型作为参数_C#笔记~泛型

一、引入泛型在实际开发中,常常会出现重复代码的问题,例如。运行结果这里的三个方法,使用不同的类型干了同样的事情。作为一个有追求的程序员,是绝不允许这样的事情发生的。我们观察发现,这三个方法除了方法名称和参数类型不同,方法体一模一样。我们知道object类型是一切类型的基类,根据里氏替换原则,子类对象可以赋值给父类,也即是说,可以使用object类型替换具体的类型。于是有基类版本的通用方法,且看下图...

weixin_39564617的博客 1553

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

java 泛型全解 - 绝对最详细

文章目录背景1、泛型的概述:1.1 泛型的由来1.2 基本概述1.3 泛型的目的1.4 实例2、泛型的使用2.1 泛型类2.2 泛型方法 背景 对于java的泛型我一直属于一知半解的,平常真心用的不多。直到阅读《Effect Java》,看到很多平常不了解的用法,才下定决心,需要系统的学习,并且记录下来。 1、泛型的概述: 1.1 泛型的由来 根据《Java编程思想》中的描述,泛型出现的动机: 有很多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类。 泛型的思想很早就存在,如C++中的

Venus 的博客 604

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

步步为赢 泛型简介

C#高级编程 第二章 泛型 /**/ //字符串是引用类型 引用类型 : object string //装箱 拆箱{  装箱  →→→值类型  引用类型  ←←←  拆箱 引用类型放在堆中值类型放在栈中 装箱: 栈 堆...

diejian1163的博客 117

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

第十一章总结 枚举与泛型

目录 11.1 枚举 11.1.1 使用枚举类型设置常量 11.1.2 深入了解枚举类型 11.1.3 使用枚举类型的优势 11.2 泛型 11.2.1 回顾"向上转型" 与"向下转型" 11.2.2 定义泛型类 11.2.3 泛型的常规用法 11.2.4泛型的高级用法 11.2.5 泛型总结 11.3 小结 11.1 枚举 11.1.1 使用枚举类型设置常量 11.1.2 深入了解枚举类型 11.1.3 使用枚举类型的优势 11.2 泛型 ...

weixin_67208871的博客 463

C#之泛型、委托、事件及其使用

/T为占位符,表示一个通用数据类型,使用时用实际类型代替//T可以很多个,以逗号隔开//泛型容器//泛型方法委托是一种全新的面相对象语言特性,运行在.Net平台;基于委托,开发事件驱动将会变得相当方便;委托可以视为一种数据类型,可以定义变量,但其是一种特殊的变量。委托定义的变量仅能接收方法(可以理解委托是方法指针)委托的映射关系//声明委托(定义一个方法原型)需要声明返回值+参数类型和个数//根据委托定义一个具体方法}//调用委托(需要先创建委托对象)--可以在另一个类中发送者。...

就随便写写.... 1177

我对java泛型的理解

今天工作中,见到了java的泛型,由于之前没接触过,理解很少,今天特意百度学习了一下。 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。   Java语言引入泛型的好处是安全简单。   在Java SE 1.5之前,没有泛型的情况的下,通过对类型Ob

invLong的专栏 521

Java总结(8)集合里的泛型

IO流: 1 IO流用来处理设备之间的数据传输。 2 java对数据的操作是通过流的方式。 3 Java用于操作流的对象都在IO包中。 4 流按操作数据分为两种:字节流(InputStream,OutputStream)与字符流(Writer,Reader)。 5 流按流向分为:输入流,输出

ActionReaction的专栏 752

关于泛型

什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。 可以在集合框架(Collection framework)中看到泛型的动机。例如,Map 类允许您向一个 Map 添加任意类的对象,即使最

zplzplzpl的专栏 344

JavaEE学习之【迭代器、泛型】

迭代器、泛型小知识

井底的青蛙 835

java泛型

多角度看 Java 中的泛型 泛型是 Sun 公司发布的 JDK 5.0 中的一个重要特性,它的最大优点是提供了程序的类型安全同可以向后兼容。为了帮助读者更好地理解和使用泛型,本文通过一些示例从基本原理,重要概念,关键技术,以及相似技术比较等多个角度对 Java 语言中的泛型技术进行了介绍,重点强调了泛型中的一些基本但又不是很好理解的概念。 为了避免和 C++ 中的模板混淆,本文

Road2010的专栏 781

java 反射和泛型

1. Java中的泛型是什么 ? 使用泛型的好处是什么? 这是在各种Java泛型面试中,一开场你就会被问到的问题中的一个,主要集中在初级和中级面试中。那些拥有Java1.4或更早版本的开发背景的人 都知道,在集合中存储对象并在使用前进行类型转换是多么的不方便。泛型防止了那种情况的发生。它提供了编译期的类型安全,确保你只能把正确类型的对象放入 集合中,避免了在运行时出现ClassCastExcep...

emmmsuperdan的博客 1051
上一篇: 搞定Android Post请求缓存(不能缓存你顺着网线过来打我)!
下一篇: Android项目创建Flutter module后运行编译失败问题
Ever69
博客等级 码龄9年 102粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值