语言中的泛型

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)实现的。

时间: 2024-10-13 22:50:53

语言中的泛型的相关文章

java中的泛型(转)

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

泛型及java中的泛型

当作笔记整理的~~~ 首先,引出堆对象这个概念. 什么是堆对象,就是程序在运行过程中可以随时建立或者删除的对象,可以用new运算符(或malloc函数)或者delete运算符(或free函数).泛型可以看作是一类堆对象. 泛型是程序设计语言的一种特性.允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明. 各种程序设计语言和其编译器.运行环境对泛型的支持均不一样.将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型. 泛型的定义主要有两种:1.在程序编

Java 中的泛型详解-Java编程思想

Java中的泛型参考了C++的模板,Java的界限是Java泛型的局限. 2.简单泛型 促成泛型出现最引人注目的一个原因就是为了创造容器类. 首先看一个只能持有单个对象的类,这个类可以明确指定其持有的对象的类型 class Holder1 { private Circle a; public Holder1(Circle a) { this.a = a; } Circle get() { return a; } } 上面的类的可重用性不怎么样,无法持有其他类型的任何对象,下面通过持有Object

转载:C#中的泛型

泛型类和泛型方法兼复用性.类型安全和高效率于一身,是与之对应的非泛型的类和方法所不及.泛型广泛用于容器(collections)和对容器操作的方 法中..NET框架2.0的类库提供一个新的命名空间System.Collections.Generic,其中包含了一些新的基于泛型的容器类.要查 找新的泛型容器类(collection classes)的示例代码,请参见基础类库中的泛型.当然,你也可以创建自己的泛型类和方法,以提供你自己的泛化的方案和设计模式,这是类型安全且高效 的.下面的示例代码以一

Swift语言中的泛型编程 【Generic】【Part 1】

泛型  泛型编程让你可以编写更具扩展性.易重用的功能,代码使用时的类型取决于你所定义的业务需求.你可以编写避免重复的代码,目标更加清晰明确,风格抽象. 泛型是Swift语言的一项强大的特性,基本上所有的swift标准库都建立在泛型代码上.实际上,你在这本书的时候不知不觉地接触到泛型,它贯穿始终.例如Swift的数组和字典类型都是泛型集合.你可以创建用于存放整数值的数组,也创建数组存储字符串,其他所有能在Swift中创建的类型都可以创建到数组中.类似的,你可以创建字典来存储数值或其他指定的类型,毫

Java中的泛型 (上) - 基本概念和原理

本节我们主要来介绍泛型的基本概念和原理 后续章节我们会介绍各种容器类,容器类可以说是日常程序开发中天天用到的,没有容器类,难以想象能开发什么真正有用的程序.而容器类是基于泛型的,不理解泛型,我们就难以深刻理解容器类.那,泛型到底是什么呢? 什么是泛型? 一个简单泛型类 我们通过一个简单的例子来说明泛型类的基本概念.实现原理和好处. 基本概念 我们直接来看代码: public class Pair<T> { T first; T second; public Pair(T first, T se

C#中的泛型-1

在软件这个行业,做的越久,往往会觉得很多技术问题最终会偏向数据结构和算法. 记得曾经大学的一堂课上,老师讲了一个关于冒泡排序的算法,下面是课本上的标准实现. 1 public class Sort 2 { 3 public void sortArray(int[] arry) 4 { 5 int length = arry.Length; 6 for (int i = 0; i <= length - 2; i++) 7 { 8 for (int j = length - 1; j >= 1;

6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pattern-and-dep/ 系列目录: Relationship in Entity Framework Using Code First Approach With Fluent API[[使用EF Code-First方式和Fluent API来探讨EF中的关系]] Code First Mig

数据处理程序语言中的基本数据类型

程序语言根据其设计目的不同,其侧重的基本数据类型也不同.JAVA.C#等语言被设计用来进行通用的应用程序开发,其基本数据类型是字符串.数字.布尔等原子数据类型,以及数组和通用对象.而SQL.PowerBuilder.R.集算器esProc等语言被设计用来进行数据处理,其基本数据类型是有结构的二维数据表对象.比如这句SQL:SELECT T1.id,T1.name,T1.value FROM T1 LEFT JOIN T2 ON T1.id=T2.id,这里的T1,T2以及计算结果就是这种数据类型