1.C#中的泛型

先写一个Demo:

namespace generic
{
        public class Program
        {
                static void Main(string[] args)
                {
                        GenericClass<int> gInt = new GenericClass<int>();
                        Console.WriteLine(gInt.GetType());
                        Console.WriteLine(gInt.ToString());                         GenericClass<string> gStr = new GenericClass<string>("Test");
                        Console.WriteLine(gStr.GetType());
                        Console.WriteLine(gStr.ToString());                         Console.Read();
                }         }         //泛型类
        public class GenericClass<T>
        {
                T _t;
                public GenericClass(T t)
                {
                        _t = t;
                }
                public override string ToString()
                {
                        return _t.ToString();
                }
        }
}

测试输出:

查看一下IL

C#当中GenericClass<T>是一个泛型类,他和.net中其他的类型一样,同样是一个确定的类型,在不指定情况下,继承自Object类,而且可以进行派生。

与普通类型不同的是,他是一种开放类型,.Net中规定开放类型是不能被实例化的,这就确保了开放类型的泛型参数再被指定之前,不会被实例化成任何对象。

(也没办法,因为也不知道开放类型需要多大的内存)

GenericClass<string> gStr = new GenericClass<string>("Test");

GenericClass<int> gInt = new GenericClass<int>(123456);

为开放式的类型提供泛型的实例导致一个封闭类型的产生,他们的关系如下:

上图可以了解到封闭类型和开放类型处于同一层次,而且没有什么关系。

综上:C#泛型类在编译时,生成中间代码IL,通用类型T只是一个占位符。在实例化类时,根据用户指定的数据类型代替T并由即时编译器(JIT)生成本地代码,这个本地代码中已经使用了实际的数据类型,等同于用实际类型写的类,所以不同的封闭类的本地代码是不一样的。按照这个原理,我们可以这样认为: 泛型类的不同的封闭类是分别不同的数据类型。

2.JAVA泛型

Java泛型的定义:泛型是JDK1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操作的数据类型被指定为一个参数,在用到的时候在指定具体的类型。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。

public class Main {

        public static void main(String[] args) {
                //定义泛型类GenericClass的一个Integer版本                 GenericClass<Integer> intOb=new GenericClass<Integer>();                 intOb.ToString();                 System.out.println("----------------------------------");                 //定义泛型类GenericClass的一个String版本                 GenericClass<String> strOb=new GenericClass<String>("Test");                 strOb.ToString();
        }
}   class GenericClass<T> {
        private T _t; //定义泛型成员变量         public GenericClass(T t) {                 this._t = t;         }         public void ToString() {                   System.out.println(_t.toString());                   }
}

结果:

C#则是真实的泛型,Java的泛型是伪泛型,怎么理解伪泛型?

正确理解泛型概念的首要前提是理解类型擦出(type erasure)。

Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。

使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉,这个过程就称为类型擦除。

如在代码中定义的GenericClass<Integer>和 GenericClass<String>等类型,在编译后都会编程GenericClass。JVM看到的只是GenericClass,而由泛型附加的类型信息对JVM来说是不可见的。

Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。

上面代码中执行结果中发现,两个版本的泛型类,都是class com.company.GenericClass,

说明泛型类型String和Integer都被擦除掉了,这个就是所谓的原始类型。

原始类型(raw type)就是擦除去了泛型信息,最后在字节码中的类型变量的真正类型。

综上:

泛型技术在C#和Java之中的使用方式看似相同,但实现上却有着根本性的分歧,C#里面泛型无论在程序源码中、编译后的IL中(Intermediate Language,中间语言,这时候泛型是一个占位符)或是运行期的CLR中都是切实存在的,List<int>与List<String>就是两个不同的类型,它们在系统运行期生成,有自己的虚方法表和类型数据,这种实现称为类型膨胀,基于这种方法实现的泛型被称为真实泛型。

Java语言中的泛型则不一样,它只在程序源码中存在,在编译后的字节码文件中,就已经被替换为原来的原始类型(Raw Type,也称为裸类型)了,并且在相应的地方插入了强制转型代码,因此对于运行期的Java语言来说,ArrayList<int>与ArrayList<String>就是同一个类。所以说泛型技术实际上是Java语言的一颗语法糖,Java语言中的泛型实现方法称为类型擦除,基于这种方法实现的泛型被称为伪泛型。

C#当中的泛型和java中的对比的更多相关文章

  1. C#的泛型和Java的伪泛型

    C#的泛型和java的伪泛型,talk is cheap,show me the code   C#泛型 下面结果,C#里面会输出false,如果这个还不能真正的说明C#的泛型是真的泛型,那就看下面这 ...

  2. java中的泛型和sql中的索引

    sql中的索引 索引:好处查询的速度快,被删除,修改,不会对表产生影响,作用是加速查询: 一种典型的数据库对象 作用:提交数据的查询效率,尤其对一些数据量很大的表 索引是用来为表服务的 索引是orac ...

  3. java中引用对比C++指针

    前置知识地址:https://blog.csdn.net/wangfei8348/article/details/51383805 重点在后面的引用对比实验(测试出内存地址,我很开心哈哈哈,客观给个好 ...

  4. MyBatis 通过包含的jdbcType类型和java中对应的数据类型

    MyBatis 通过包含的jdbcType类型 BIT         FLOAT      CHAR           TIMESTAMP       OTHER       UNDEFINED ...

  5. 1.什么是泛型和C#中泛型在Class上的实现

    阅读目录 一:什么是泛型? 二:C#中泛型在Class上的实现   一:什么是泛型? 我们在编程的时候需要一个数据类型,但是在刚开始的时候还不确定这个数据类型是怎么样的,或者说对于不同的多个数据类型有 ...

  6. Java泛型学习笔记--Java泛型和C#泛型比较学习(一)

    总结Java的泛型前,先简单的介绍下C#的泛型,通过对比,比较学习Java泛型的目的和设计意图.C#泛型是C#语言2.0和通用语言运行时(CLR)同时支持的一个特性(这一点是导致C#泛型和Java泛型 ...

  7. 关于Java 中Integer 和Long对象 对比的陷阱(简单却容易犯的错误)

    彩票客户端“忘记密码”功能有bug,今天调试时,发现了原因: 功能模块中有一段: if(userpo.getId()!=Long.valueOf(uid)){ throw new VerifyExce ...

  8. Java与Swift对比

    本文链接:http://blog.csdn.net/msyqmsyq/article/details/53538159 从Java到Swift还是比较简单的,相比Object-C,Swift和Java ...

  9. iOS 开发学习-类的创建与实现,与java语言的对比

    Person.h #import <Foundation/Foundation.h> @interface Person : NSObject { //在{}中定义属性(全局变量/实例变量 ...

随机推荐

  1. 教程-Delphi第三方控件安装卸载指南

    1 只有一个DCU文件的组件.DCU文件是编译好的单元文件,这样的组件是作者不想把源码公布.一般来说,作者必须说明此组件适合Delphi的哪种版本,如果版本不对,在安装时就会出现错误.也正是因为没有源 ...

  2. keil编译STM32工程时 #error directive: "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"

    我们可以双击错误,然后会自动定位到文件 stm32f10x.h 中出错的地方,可以看到代码: #if !defined (STM32F10X_LD) && !defined (STM3 ...

  3. UIImagePickerController Class 概述

    不能定制界面,不可派生子类. 使用步骤: 检查制定源是否可用. isSourceTypeAvailable:方法.    检查可用媒体(视频还是只能是图片) availableMediaTypesFo ...

  4. Google maps library的使用

    公司的项目中用到了google地图API, 使用Google API开发就会用到Marker, 用来在google 地图上标注位置 但是google marker使用过程中也有个问题,就是如果在goo ...

  5. win32进阶之路:给锁屏软件增加一个超链接按钮

    前言: windows下一切皆窗口,我们看到的超链接也是窗口,效果图如下: 鼠标放在赵大哥博客园主页和关于软件两个按钮上,按钮上的字体会从绿色变成红色,同时鼠标指针变为手型,点下鼠标左键就会调用默认浏 ...

  6. Java算法试题--猜字母/杀人游戏

    题目例如以下: 把abcd-s共19个字母组成的序列反复拼接106次,得到长度为2014的串. 接下来删除第1个字母(即开头的字母a).以及第3个,第5个等全部奇数位置的字母. 得到的新串再进行删除奇 ...

  7. Project Management - 3) Manage Your Meetings

    1. 取消没有价值的会议 会议是有代价和成本的 不要举行顺序式的多人进度报告会议 eg: 这周做了什么,下周还要做什么? 除了发言人和项目经理外,每个人都会觉得无聊. 这种会议是在拖项目的后腿,赶紧停 ...

  8. cdoj 92 Journey tarjan/lca 树上点对距离

    Journey Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/92 Descri ...

  9. linux tomca几个配置文件及点

    --------------------推荐----配置2---------------------<Connector port="8081"executor=" ...

  10. 使用air进行移动app开发常见功能和问题(一)

    1.  获取最近联系人 思路:侦听Geolocation的update事件,获取经度和纬度信息,再把坐标信息上传至服务器,服务器比较坐标信息算出距离,返回最近位置的若干个人. update时间在2种情 ...