上海行业门户网站建设工具比较知名的设计网站有哪些
2026/6/1 10:08:51 网站建设 项目流程
上海行业门户网站建设工具,比较知名的设计网站有哪些,wordpress安装语言设置中文,沪尚茗居装修价格怎样说说你对泛型的理解 章节目录 文章目录说说你对泛型的理解简答一、泛型概述什么是泛型#xff1f;为什么要使用泛型#xff1f;泛型使用场景泛型的好处二、泛型类三、泛型方法四、泛型接口五、类型擦除什么是类型擦除类型擦除的原理小结简答 泛型是Java中的一个特性#x…说说你对泛型的理解章节目录文章目录说说你对泛型的理解简答一、泛型概述什么是泛型为什么要使用泛型泛型使用场景泛型的好处二、泛型类三、泛型方法四、泛型接口五、类型擦除什么是类型擦除类型擦除的原理小结简答泛型是Java中的一个特性它允许我们在定义类、接口或方法时使用类型参数以实现代码的通用性和安全性。泛型的目的是在编译时进行类型检查并提供编译期间的类型安全。泛型的理解包括以下几个方面**首先**泛型提供了代码重用和通用性。通过使用泛型我们可以编写可重用的代码可以在不同的数据类型上执行相同的操作。这样我们可以避免重复编写类似的代码提高了开发效率。**其次**泛型强调类型安全。编译器可以在编译时进行类型检查阻止不符合类型约束的操作。这样可以避免在运行时出现类型错误的可能增加了程序的稳定性和可靠性。**另外**使用泛型可以避免大量的类型转换和强制类型转换操作。在使用泛型集合类时不需要进行强制类型转换可以直接获取正确的数据类型提高了代码的可读性和维护性。**此外**泛型还可以在编译时进行类型检查提前发现潜在的类型错误。这种类型检查是在编译时进行的避免了一些常见的运行时类型异常减少了错误的可能性。**最后**泛型可以增加代码的可读性和可维护性。通过使用泛型我们可以明确指定数据类型并在代码中表达清晰使得其他开发人员更容易理解代码的意图和功能。一、泛型概述什么是泛型为什么要使用泛型泛型即“参数化类型”。一提到参数最熟悉的就是定义方法时有形参列表普通方法的形参列表中每个形参的数据类型是确定的而变量是一个参数。在调用普通方法时需要传入对应形参数据类型的变量实参若传入的实参与形参定义的数据类型不匹配则会报错那参数化类型是什么以方法的定义为例在方法定义时将方法签名中的形参的数据类型也设置为参数也可称之为类型参数在调用该方法时再从外部传入一个具体的数据类型和变量。泛型的本质是为了将类型参数化 也就是说在泛型使用过程中数据类型被设置为一个参数在使用时再从外部传入一个数据类型而一旦传入了具体的数据类型后传入变量实参的数据类型如果不匹配编译器就会直接报错。这种参数化类型可以用在类、接口和方法中分别被称为泛型类、泛型接口、泛型方法。泛型使用场景在 ArrayList 集合中可以放入所有类型的对象假设现在需要一个只存储了 String 类型对象的 ArrayList 集合。publicclassdemo1{publicstaticvoidmain(String[]args){ArrayListStringlistnewArrayList();list.add(a);list.add(b);list.add(c);for(Strings:list){System.out.println(s);}}}//上面代码没有任何问题在遍历 ArrayList 集合时只需将 Object 对象进行向下转型成 String 类型即可得到 String 类型对象。// 但如果在添加 String 对象时不小心添加了一个 Integer 对象会发生什么看下面代码publicstaticvoidmain(String[]args){ArrayListlistnewArrayList();list.add(aaa);list.add(bbb);list.add(ccc);list.add(666);for(inti0;ilist.size();i){System.out.println((String)list.get(i));}}上述代码在编译时没有报错但在运行时却抛出了一个 ClassCastException 异常其原因是 Integer 对象不能强转为 String 类型。那如何可以避免上述异常的出现即我们希望当我们向集合中添加了不符合类型要求的对象时编译器能直接给我们报错而不是在程序运行后才产生异常。这个时候便可以使用泛型了。publicstaticvoidmain(String[]args){ArrayListStringlistnewArrayList();list.add(aaa);list.add(bbb);list.add(ccc);//list.add(666);// 在编译阶段编译器会报错for(inti0;ilist.size();i){System.out.println(list.get(i));}} String 是一个泛型其限制了 ArrayList 集合中存放对象的数据类型只能是 String当添加一个非 String 对象时编译器会直接报错。这样我们便解决了上面产生的 ClassCastException 异常的问题这样体现了泛型的类型安全检测机制。泛型的好处统一数据类型对于后续业务层中取出数据有很强的统一规范性方便对数据的管理把运行时期的问题提前到了编译期避免了强转类型转换可能出现的异常降低了程序出错的概率二、泛型类泛型类的使用场景当一个类中某个变量的数据不确定时就可以定义带有泛型的类。我们平常所用的ArrayList类就是一个泛型类我们看如下源码ArrayList 源码上显示在ArrayList类的后面便是 泛型定义了这样的泛型就可以让使用者在创建ArrayList对象时自主定义要存放的数据类型。这里的 E 可以理解成变量它不是用来记录数据的而是记录数据的类型的。可以写成很多字母TVK都可以通常这些字母都是英文单词的首字母V表示 valueK表示 keyE表示 elementT表示 type如果你想自己练习的时候写成ABCDEFG都可以但建议养成好习惯用专业名词的首字母便于理解。T 代表一般的任何类E 代表 Element 元素的意思或者 Exception 异常的意思K 代表 Key 的意思V 代表 Value 的意思通常与 K 一起配合使用S 代表 Subtype 的意思文章后面部分会讲解示意。三、泛型方法我们什么时候会用到泛型方法呢通常情况下当一个方法的形参不确定的情况下我们会使用到泛型方法。泛型方法其实与泛型类有着紧密的联系通过上面我写的自定义泛型类不难看出在泛型类中所有方法都可以使用类上定义的泛型。但是泛型方法却可以脱离泛型类单独存在泛型方法上定义的泛型只有本方法上可以使用其他方法不可用。publicstaticEvoidaddAll(ArrayListElist,E...e1){for(Ee:e1){list.add(e);}}四、泛型接口泛型接口与泛型方法相似当我们的接口中参数类型不确定的时候就可以使用泛型。publicinterfaceMyListE{// 定义一个方法做简单测试publicbooleanadd(Ee);}五、类型擦除什么是类型擦除编译器编译带类型说明的集合时会去掉类型信息泛型的本质是将数据类型参数化它通过擦除的方式来实现即编译器会在编译期间擦除代码中的所有泛型语法并相应的做出一些类型转换动作。换而言之泛型信息只存在于代码编译阶段在代码编译结束后与泛型相关的信息会被擦除掉专业术语叫做类型擦除。也就是说成功编译过后的 class 文件中不包含任何泛型信息泛型信息不会进入到运行时阶段。其实Java中的泛型本质是伪泛型当把集合定义为string类型的时候,当数据添加在集合当中的时候,仅仅在门口检查了一下数据是否符合String类型, 如果是String类型,就添加成功,当添加成功以后,集合还是会把这些数据当做Object类型处理,当往外获取的时候,集合在把他强转String类型当代码编译到class文件的时候,泛型就消失,叫泛型的擦除publicclassGenericType{publicstaticvoidmain(String[]args){ArrayListarrayStringnewArrayList()String;ArrayListarrayIntegernewArrayList()Integer;System.out.println(arrayString.getClass()arrayInteger.getClass());// true}}在这个例子中我们定义了两个 ArrayList 集合不过一个是 ArrayList String只能存储字符串。一个是 ArrayList Integer只能存储整型对象。我们通过 arrayString 对象和 arrayInteger 对象的 getClass() 方法获取它们的类信息并比较发现结果为true。明明我们在 中传入了两种不同的数据类型那为什么它们的类信息还是相同呢 这是因为在编译期间所有的泛型信息都会被擦除 ArrayList Integer 和 ArrayList String 类型在编译后都会变成ArrayList Objec t类型。[!CAUTION]那么是不是所有的类型参数被擦除后都以 Object 类进行替换呢答案是否定的大部分情况下类型参数 T 被擦除后都会以 Object 类进行替换而有一种情况则不是那就是使用到了 extends 和 super 语法的有界类型参数上界T extends Something或下界T super Something)类型擦除的原理假如我们定义了一个 ArrayList Integer 泛型集合若向该集合中插入 String 类型的对象不需要运行程序编译器就会直接报错。这里可能有小伙伴就产生了疑问不是说泛型信息在编译的时候就会被擦除掉吗那既然泛型信息被擦除了如何保证我们在集合中只添加指定的数据类型的对象呢换而言之我们虽然定义了 ArrayList Integer 泛型集合但其泛型信息最终被擦除后就变成了 ArrayList Object 集合那为什么不允许向其中插入 String 对象呢Java 是如何解决这个问题的其实在创建一个泛型类的对象时 Java 编译器是先检查代码中传入 T 的数据类型并记录下来然后再对代码进行编译编译的同时进行类型擦除如果需要对被擦除了泛型信息的对象进行操作编译器会自动将对象进行类型转换。可以把泛型的类型安全检查机制和类型擦除想象成演唱会的验票机制以 ArrayList Integer 泛型集合为例。当我们在创建一个 ArrayList Integer 泛型集合的时候ArrayList 可以看作是演唱会场馆而 T 就是场馆的验票系统Integer 是验票系统设置的门票类型当验票系统设置好为 Integer 后只有持有 Integer 门票的人才可以通过验票系统进入演唱会场馆集合中若是未持有 Integer 门票的人想进场则验票系统会发出警告编译器报错。在通过验票系统时门票会被收掉类型擦除但场馆后台JVM会记录下观众信息泛型信息。进场后的观众变成了没有门票的普通人原始数据类型。但是在需要查看观众的信息时操作对象场馆后台可以找到记录的观众信息编译器会自动将对象进行类型转换。publicclassGenericType{publicstaticvoidmain(String[]args){ArrayListarrayIntegernewArrayList();// 设置验票系统arrayInteger.add(111);// 观众进场验票系统验票门票会被收走类型擦除IntegernarrayInteger.get(0);// 获取观众信息编译器会进行强制类型转换System.out.println(n);}}擦除 ArrayList Integer 的泛型信息后get() 方法的返回值将返回 Object 类型但编译器会自动插入 Integer 的强制类型转换。也就是说编译器把 get() 方法调用翻译为两条字节码指令对原始方法 get() 的调用返回的是 Object 类型将返回的 Object 类型强制转换为 Integer 类型IntegernarrayInteger.get(0);// 这条代码底层如下//1get() 方法的返回值返回的是 Object 类型ObjectobjectarrayInteger.get(0);//2编译器自动插入 Integer 的强制类型转换Integern(Integer)object;小结1.泛型信息包括泛型类、接口、方法只在代码编译阶段存在在代码成功编译后其内的所有泛型信息都会被擦除并且类型参数 T 会被统一替换为其原始类型默认是 Object 类若有 extends 或者 super 则另外分析2.在泛型信息被擦除后若还需要使用到对象相关的泛型信息编译器底层会自动进行类型转换从原始类型转换为未擦除前的数据类型。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询