语言中的泛型

author author     2022-08-29     306

关键词:

java的设计采用了单根结构,除去在GC上的好处之外,在泛型编程上(模板C++),因为所有的类型都继承自Object,因此利用向上塑型,我们是可以写出如下的代码:

public class GenericTest {

public static void main(String[] args) {
List list = new ArrayList();
list.add("qqyumidi");
list.add("corn");
list.add(100);

for (int i = 0; i < list.size(); i++) {
String name = (String) list.get(i); // exception
System.out.println("name:" + name);
}
}
}
可以看到,不需要显示的模板声明,我们是可以把string和int都放入List里,但是问题是在向下塑型的过程中,如果把int转成string是不行的,java使用Exception来处理此种情况。

Java SE5之后也引入了参数化类型的概念,也就是泛型:
List<String> list = new ArrayList<String>();
list.add("qqyumidi");
list.add("corn");
//list.add(100); // 提示编译错误

这就是二者都遵循的泛型,但是java的泛型实现与c++是不同的:
public class GenericTest {

public static void main(String[] args) {

Box<String> name = new Box<String>("corn");
Box<Integer> age = new Box<Integer>(712);

System.out.println("name class:" + name.getClass()); // com.qqyumidi.Box
System.out.println("age class:" + age.getClass()); // com.qqyumidi.Box
System.out.println(name.getClass() == age.getClass()); // true

}

}
可以看到,在运行时,不同的泛型实际上是用一个类型,同样意义的代码在c++里完全是两回事情:
在于Java中的泛型这一概念提出的目的,导致其只是作用于代码编译阶段,在编译过程中,对于正确检验泛型结果后,会将泛型的相关信息擦出,也就是说,成功编译过后的class文件中是不包含任何泛型信息的。泛型信息不会进入到运行时阶段。

原始类型(raw type)就是擦除去了泛型信息,最后在字节码中的类型变量的真正类型。无论何时定义一个泛型类型,相应的原始类型都会被自动地提供。类型变量被擦除(crased),并使用其限定类型(无限定的变量用Object)替换。

Java代码  

1. class Pair<T> {    
2.   private T value;    
3.   public T getValue() {    
4.     return value;    
5.   }    
6.   public void setValue(T  value) {    
7.     this.value = value;    
8.   }    
9. }    
 Pair<T>的原始类型为:
Java代码  

1. class Pair {    
2.   private Object value;    
3.   public Object getValue() {    
4.     return value;    
5.   }    
6.   public void setValue(Object  value) {    
7.     this.value = value;    
8.   }    
9. }  

 

编译器如何处理泛型?
     通常情况下,一个编译器处理泛型有两种方式:
     1.Code specialization。在实例化一个泛型类或泛型方法时都产生一份新的目标代码(字节码or二进制代码)。例如,针对一个泛型list,可能需要 针对string,integer,float产生三份目标代码。
     2.Code sharing。对每个泛型类只生成唯一的一份目标代码;该泛型类的所有实例都映射到这份目标代码上,在需要的时候执行类型检查和类型转换。
     C++中的模板(template)是典型的Code specialization实现。C++编译器会为每一个泛型类实例生成一份执行代码。执行代码中integer list和string list是两种不同的类型。这样会导致代码膨胀(code bloat),不过有经验的C++程序员可以有技巧的避免代码膨胀。
     Code specialization另外一个弊端是在引用类型系统中,浪费空间,因为引用类型集合中元素本质上都是一个指针。没必要为每个类型都产生一份执行代码。而这也是Java编译器中采用Code sharing方式处理泛型的主要原因。
     Java编译器通过Code sharing方式为每个泛型类型创建唯一的字节码表示,并且将该泛型类型的实例都映射到这个唯一的字节码表示上。将多种泛型类形实例映射到唯一的字节码表示是通过类型擦除(type erasue)实现的。

 

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

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

Swift 中的泛型数组

】Swift中的泛型数组【英文标题】:ArraysofGenericsinSwift【发布时间】:2015-04-2211:50:24【问题描述】:我一直在玩不同类型的泛型类数组。用一些示例代码最容易解释我的问题://Obviouslyaverypointlessprotocol...protocolMyProtocolvarvalue:Selfgete... 查看详情

c语言的泛型编程

...。template<typenameT>voidMySwap(T&a,T&b){ Tc=a; a=b; b=c;}3C语言的泛型  我的第一想法是既然不能直接交换变量(类型不知道),那就交换指针呀。 查看详情

java中的泛型

...的泛型,在实际声明时可以用特定的引用类型替代<>中的字母,如 ArrayList<String>arrString=newArrayList<>(); 该语句实现了指向String对象的ArrayList容器的声明。 2.泛 查看详情

c#中的泛型

前言这篇文章和大家一起学习泛型。我们目前使用的语言结构,可以建立多种不同类型的强大对象。具体步骤是声明类,封装需要的行为之后创建类的实例对象。目前为止,所有类声明用到的类型都是特定类型。有可... 查看详情

java中的泛型方法

java中的泛型方法:是否拥有泛型方法。与其所在的类是否泛型没有关系。泛型的声明,必须在方法的修饰符(public,static,final,abstract等)之后。返回值声明之前。和泛型类一样,能够声明多个泛型,用逗号隔开。一个st... 查看详情

覆盖方法中的泛型

】覆盖方法中的泛型【英文标题】:Genericsinoverriddenmethods【发布时间】:2013-04-0404:04:20【问题描述】:遇到了一个有趣的问题;以下类编译:publicclassTestpublicstaticvoidmain(String[]args)throwsExceptionAa=newA();Bb=newB();foo(a);foo(b);privatestaticvoi... 查看详情

java中的泛型

泛型的概念泛型:  泛型是一种末知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型  泛型也可以看成是一个变量用来接收数据类型  Ee:Element元素  Tt:Type类型是否使用泛型的对比不使用泛型/***... 查看详情

数组中的泛型联合

】数组中的泛型联合【英文标题】:Unionofgenericsinarray【发布时间】:2022-01-2220:14:14【问题描述】:我试图在数组中获取泛型的联合类型,但只能检索泛型从实际实现中扩展的内容。typeParams=Record<string,number|string|null|undefined>|u... 查看详情

将泛型值推送到 Typescript 中泛型类中的泛型列表

】将泛型值推送到Typescript中泛型类中的泛型列表【英文标题】:PushinggenericvalueontogenericlistinagenericclassinTypescript【发布时间】:2019-10-0713:38:28【问题描述】:我正在尝试将泛型对象推送到泛型类中的泛型对象列表中。这可能只是... 查看详情

c#中的泛型是啥意思?

泛型是2.0版C#语言和公共语言运行库(CLR)中的一个新功能。泛型将类型参数的概念引入.NETFramework,类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时... 查看详情

java开发知识之java中的泛型

        Java开发知识之Java中的泛型一丶简介什么是泛型.    泛型就是指泛指任何数据类型.就是把数据类型用泛型替代了.这样是可以的.二丶Java中的泛型  Java中,所有类的父类都是Object类.所以定义泛型的时候,设... 查看详情

Java中的泛型无效

】Java中的泛型无效【英文标题】:voidwithGenericsinJava【发布时间】:2021-12-2215:13:56【问题描述】:我有一个返回void的函数publicinterfaceIProductServicevoiddelete(Stringid);通用方法publicinterfaceIRequestHandler<C,R>Rhandler(Cc);Class<C>commandTyp... 查看详情

聊聊c#和c++中的泛型模板底层玩法

...们底层是怎么玩的?一:C++中的模板玩法毕竟C++是兼容C语言,而C是过程式的玩法,所以C++就出现了两种模板类型,分别为:函数模板 查看详情

jdk中的泛型

Java中的泛型介绍:  起因:    1.JDK1.4 以前类型不明确:     ① 装入集合的对象被当作Object 类型对待,从而失去了自己的原有类型;              ②&nb... 查看详情

Java中的泛型数组

】Java中的泛型数组【英文标题】:GenericarraysinJava【发布时间】:2022-01-1702:36:17【问题描述】:好的,我一直在网上搜索,但似乎找不到任何解决问题的方法。我找到了很多解决方案,但没有一个适合。我需要创建一个泛型数组... 查看详情

C# 中的泛型与非泛型性能

】C#中的泛型与非泛型性能【英文标题】:Genericvsnot-genericperformanceinC#【发布时间】:2013-06-2520:53:27【问题描述】:我写了两个等价的方法:staticboolF<T>(Ta,Tb)whereT:classreturna==b;staticboolF2(Aa,Ab)returna==b;时差:00:00:00.038002200:00:00.01... 查看详情

javascript中的泛型列表

TheclosesttoagenericListinjavascript.Whencallingconstructor-newList(Module)-addmodelinconstructorparameter/******************//***Listclass***//******************/(function(){ fu 查看详情