都说C#就是java,大侠们能否就C#与java作一个详细的对比?? 两个差不多了,如果你学JAVA就学JAVA罢了,又学什么C#,这样你还得适应一段时间才行 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 从语言上说c#是java的一个翻版。但还不如java那么成熟和完善。java相对于c#不光是语言方面的问题,关键是J2EE企业级平台规范对C#散兵游勇的问题。类似于IBM服务器对家里的多媒体电脑。 转 robbin CLR和JRE的运行机制的初步总结概念比较: Java C# byte code IL(字节码,中间语言) jvm.dll mscrolib.dll,mscrojit.dll(虚拟机) JRE CLR(运行环境) JDK .Net Framework(开发框架) package assembly(类库,程序集) 一、关于类库的版本管理问题 Java和C#代码运行要依靠其运行环境(JRE,CLR)和运行环境带的基础类库(C#称为配件或者程序集Assembly),此外还会有一些第三方的类库或者自己开发的类库。如果运行环境版本不一致,或者引用的类库版本不一致都会带来程序不能正常运行。比如一个Java程序是在JDK1.2上开发,如果在JRE1.4上运行,一般情况下可以向下兼容,但也有例外,有些GUI程序在JDK1.4上面运行结果很可能会不同。 JRE的版本管理 Java的解决办法是每个程序自己携带一套JRE。 我的机器上已经被安装了好多套JRE和JDK了(JDK包括了同版本的JRE,此外还包括有编译器和其它工具),它们分别是: BEA Weblogic Server 7.0 自带一套 JDK1.3.1_02 我下载了一套最新的JDK1.4.1_02 JBuilder9自带一套JKD1.4.1_02 Oracle8.1.7自带一套JRE1.1.7 Ration Rose自带一套JDK1.3 DreamWeaver自带一套JDK1.3 6套JRE,每套JRE都被各自安装到不同的目录,不会互相影响。当在控制台执行java.exe,操作系统寻找JRE的方式如下: 先找当前目录下有没有JRE 再找父目录下有没有JRE 接着在PATH路径中找JRE 注册表HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\ 查看CurrentVersion的键值指向哪个JRE 最常用的是在PATH路径中找JRE,一般情况下,自己的程序运行之前都会先在批处理文件里面临时设置PATH,把自己用的JRE放到PATH路径最前面,所以肯定会运行自己带的JRE,不会造成版本混乱。 .Net Framework的版本管理 .Net Framework被固定安装在C:\Winnt\Microsoft.NET\Framework\v版本号\目录下,听说刚发行的.Net Framework1.1已经对1.0做了很多改进,也许在旧版本的.Net Framework开发的程序在往新版本上面迁移的时候需要部分修改。 JRE的基础类库 JRE自带的基础类库主要是JRE\lib\rt.jar这个文件,包括了Java2平台标准版的所有类库。和JRE的版本一致。 .Net Framekwork的核心类库 .Net Framekwork的核心类库被放置在C:\Winnt\assembly\gac\目录下,按照不同的名称空间放在不同目录中,不像JRE打成了一个包。并且可以同时存在不同的版本,例如: 某类库1.0版本 C:\Winnt\assembly\gac\名称\1.0\名称.dll 某类库1.1版本 C:\Winnt\assembly\gac\名称\1.1\名称.dll 这样做,虽然很灵活,可以随时把类库更新到最新的状态,但是很容易带来版本管理的复杂度,造成版本不一致。 JRE类库的查找方法和版本管理 JRE中由ClassLoader负责查找和加载程序引用到的类库,基础类库ClassLoader会到rt.jar中自动加载,其它的类库,ClassLoader在环境变量CLASSPATH指定的路径中搜索,按照先来先到的原则,放在CLASSPATH前面的类库先被搜到,Java程序启动之前建议先把PATH和CLASSPATH环境变量设好,OS通过PATH来找JRE,确定基础类库rt.jar的位置,JRE的ClassLoader通过CLASSPATH找其它类库。但有时候会出现这样的情况,希望替换基础类库中的类库,那么也可以简单的通过-Djava.endrosed.path=...参数传递给java.exe,于是ClassLoader会先于基础类库使用java.endrosed.path参数指定路径的类库。因此Java的版本管理是非常简单有效的,也许很原始,不过很好用,简单就不容易出错。(所以我很奇怪Eric Ramond为什么批评Java的类库管理机制,他还居然批评Java的接口,令人怀疑他对Java的了解程度) .Net Framework的类库管理机制 .Net Framework的类库管理机制相当强大和复杂,分为私有类库和共享类库。 私有类库就放在exe程序当前路径下,或其相对路径中,只有当前程序可见。 共享类库需要在GAC(Global Assembly Cache)中注册,注册过程比较复杂,首先要用工具生成公开/私有密钥对,然后结合密钥和类库版本号连编,最后使用工具注册到GAC中好以后,会被放在"C:\Winnt\assembly\gac\类库的名称空间\版本号\"目录下,不同的类库版本在注册的时候会按照版本号分开放置: 某类库1.0版本 C:\Winnt\assembly\gac\名称\1.0\名称.dll 某类库1.1版本 C:\Winnt\assembly\gac\名称\1.1\名称.dll 也就是可以同时存在一个类库的n个版本,至于在程序中用哪个版本,在程序的配置文件中声明,CLR会根据声明来调用相应的版本的类库。我觉得.Net实现方法未免太复杂了一些,将所有共享类库都塞到一个系统目录下,并且同一个类库还有n个版本,将来.Net第三方开发的类库逐渐丰富起来以后,.Net类库的GAC也会越来越庞大,会不会也搞得和Windows注册表一样难以维护?软件发布到服务器上的时候,类库要再注册一次,服务器会逐渐形成一个庞大的树状的GAC,GAC里面存放着组件的n个版本。试想经过一段时间之后,C:\Winnt\assembly\gac\目录会越来越庞大,有的组件甚至有n个版本都放在那里,你又不敢随便删除,不知道是不是有程序需要使用,我不明白MS为什么要把这么简单的事情搞到这么复杂? 综上所述,Java的版本管理方式简单而有效,C#的版本管理方式功能强大,不过是不是太复杂了?会不会搞成第二个注册表一样的东西? 二、虚拟机启动和加载类库的方式 Java的虚拟机启动和加载类库 在Console执行java.exe xxx命令以后,如前所述的寻找JRE,OS找到JRE目录,根据java.exe的传递参数,选择加载Server版的jvm.dll还是Client版的jvm.dll,然后加载jvm.dll,把控制权交给jvm.dll。 接下来,jvm.dll进行初始化,分配内存等等动作,然后在CLASSPATH路径中寻找class,找到class以后,寻找class中的程序入口点Main函数,然后从Main函数执行程序,在执行过程中,使用ClassLoader动态加载一系列引用到的类。当调用到native方法时,jvm.dll告诉OS在JRE\bin目录下寻找某某DLL文件,调入内存,于是实现了JNI调用。 .Net的虚拟机的启动推测 我对.Net的虚拟机的启动过程还一知半解,自己写了一些例程,并且用内存工具来检测观察,推测.Net的运行机制,先来抛砖引玉,请熟悉Windows平台编程的朋友指教。.Net有3个目录中的文件在执行的时候会被加载 1、C:\WINNT\Microsoft.NET\Framework\v版本号\ 该目录下的mscorlib.dll,mscorrsn.dll,mscorwsk.dll,mscorjit.dll是核心DLL,大概是运行虚拟机的必要文件,其中mscrolib.dll是入口点。此外,该目录下还有一些.Net的System名称空间的IL类库,与C:\Winnt\assembly\gac\相应目录下的IL类库完全一样,这些是最核心的基础类库。.Net的编译器,检查器等等工具软件也在该目录,推测System名称空间的核心类库之所以在这个目录下copy一份是因为作为.Net的编译器等工具的私有类库之用。 2、C:\Winnt\assembly\gac\ 该目录下放置.Net共享类库,如前所述 3、C:\Winnt\assembly\nativeimages_.Net版本号\ 在该目录下也有一些以System名称空间开头的核心类库,推测是MS为了加快CLR的执行效率把核心类库进行本地化,编译为native image的同名DLL。可以观察到该目录下的同名DLL文件,比GAC目录下的同名DLL文件体积大,可能是因为link底层DLL库的缘故。 某核心类库 C:\Winnt\assembly\nativeimages_.Net版本号\名称空间\.Net版本号_散列码\名称.dll 另外值得注意的地方是有两个mscorlib.dll 1、C:\WINNT\Microsoft.NET\Framework\v版本号\mscrolib.dll (1.88MB) 2、C:\WINNT\assembly\NativeImages1_v版本号\mscorlib\版本号__散列码\mscrolib.dll (3.07MB) mscrolib.dll (1.88MB)还是一个IL码的版本,所以映射了一个native的版本的mscrolib.dll (3.07MB),来加快CLR的速度。 当IL的exe程序被双击执行时,OS Loader读入程序,识别出是IL,根据IL内部的引用定义,加载mscorlib.dll,而mscorlib.dll也是IL,内部引用C:\winnt\system32\mscoree.dll,于是再加载mscoree.dll,然后把控制权交给mscoree.dll,mscoree.dll接着加载mscrorsn.dll,mscrowsk.dll,mscrojit.dll,为了加快mscorlib.dll的调用,加载mscorlib.dll的native image版本,然后由mscorlib.dll接管控制权(不知道这两个mscorlib.dll是如何来上管IL,下连native code的?)最后寻找IL码程序的入口点Main函数,开始执行程序,在执行过程中,使用Class Loader动态加载一系列引用到的类,在当前路径下,在共享类库的GAC中查找等等。 这里和jvm.dll不同的一点是,jvm.dll加载的基础类库和加载其它类库方式完全一样,全部都是字节码的class。而mscrolib.dll加载以System名称开头的核心类库的时候,使用了“不正当竞争手法”。mscrolib.dll从GAC中加载共享核心类库之后,又C:\Winnt\assembly\nativeimages_.Net版本号\名称空间\ 目录下加载了核心类库的native版本,这样一来,自然CLR运行起来要快多了。特别是图形图像类库全部都有native映射版本,所以CLR上运行GUI焉能不快? 对比CLR和JRE的加载过程,比较不同的地方是mscorlib.dll和System核心类库都有一个native image,可能这是CLR运行速度比较快的一个主要原因吧。 分析完以后有一个特别明显的感受,Java的底层运行机制设计的特别简单,而.Net的底层运行机制设计的特别复杂。但是在企业层刚好相反,J2EE设计的特别复杂,而.Net却设计的特别简单,真是有意思! Java的底层机制设计虽然简单,但是很健壮,.Net设计使得它的CLR速度快,类库管理功能强大,但是不是比Java更优秀,还要等以后慢慢看了。 研究了一下C#和.Net,有很多体会,好的不好的都有。随便谈谈,供大家参考。 先说说它的优点: 1、C#保留了对底层操作系统API的直接调用和指针。肯定是因为看到了Java的速度问题以及JNI的笨重,所以在设计C#时特意保留了这些C++的特性,避免了重导覆辙,也使得C#可以用来开发系统软件。普通应用都是调用.Net的程序集(相当于Java的类库,程序集里面都是byte code,不是native code),对于速度敏感,或者平台相关型应用,直接通过特定声明来调用Windows API。这样就可以功能,效率和速度都兼顾,解决各种各样的应用层问题和系统层问题(可以用C#来写系统软件了),用一种语言来解决所有场合的大部分问题,所以MS对C#很有信心。 不过实际上完全用C#开发系统软件还是不太可能的,毕竟经过C#的包装以后,比纯种的C还是要稍微慢一些,但是肯定比纯种的C#字节码快太多了。但是当你用C#开发应用软件的时候,却不可避免的涉及到底层调用的时候,可以方便的直接用C#来实现,不用像Java那样束手无策的去向C++求救,通过笨拙的JNI调用,显得高明。 2、在Windows平台上.Net CLR比Java的JRE速度快,联想到当年MS做的JVM,所以也不是很奇怪。只不过CLR速度足够快的话,C#字节码运行起来,普通应用就不会感觉出来速度比纯本地代码慢。我的感觉就是这样,基本上感觉不出来CLR启动和加载程序集的明显延迟,而不管用AWT,Swing还是SWT,JVM启动和加载类库的延迟是非常明显的,这就是真正不妙的地方了,不管Sun,IBM,BEA还是Open Souce 社区,在JVM的效率上还要继续加油。 3、开发工具IDE,老生常谈了,不过确实也很重要,对比一下Visual .Net Studio和做的最好的JavaIDE,JBuilder或者Eclipse吧,不在一个级别上。写普通的软件,甚至Web应用,IDE作用不明显,特别是对于有Unix背景的人来说,更愿意使用纯文本工具。但是涉及到GUI开发和企业应用的开发,一个强大的工具是必须的。 GUI开发来说,Visual .Net Studio开发GUI就如同使用VB开发GUI,方便和快捷的难以想像,再加上C#的程序集比VB的控件集,比VC的MFC的设计优秀的不在同一个级别上。所以在开发GUI方面,C#比VB还更加优秀,基本上和Borland的C++ Builder的水平相当,其操作的便捷还在其之上。 反观Java,Eclipse空有一个SWT,也不去做一个好点的GUI开发环境出来。JBuilder是公认的最好的Java GUI开发IDE,但是仍然难用的很,为什么?关键处还在于AWT,Swing和SWT图形库的布局设计上。 这3个图形库统统都是使用布局管理器来布局,布局好了以后才能放控件。不能够直接拖放控件实现绝对像素定位,也很难实现对控件大小,位置的操纵。 这也是有一定的原因,Java为了实现跨平台的GUI,因此不能够使用像素定位,否则在不同平台会有不同的外观表现。 而C#就不管那么多了,既然只在Windows平台上实现,直接就采用像素定位(当然布局定位也可以用),外观的控制自然可以“所见即所得”了。 由于这个先天的原因,Java的GUI开发是不可能比C#更方便的,JBuilder能做到这样,也差不多到极致了,大家也只能忍受了。 企业开发方面,C#需要SQL Server(Oracle也可以,但是不如SQL Server方便),IIS和MTS的配合,Java需要DB,App Server的配合。由于C#只管SQL Server和IIS,甚至只管IE浏览器,所以Visual .Net Studio可以做的很方便,整个开发过程一体化,不用考虑其它的实现。而JBuilder需要考虑各种不同的软件实现,特别是App Server,简直就是五花八门,JBuilder能够做到这样,在图形设计器里面设计EJB,从DB里面导入Entity Bean,方便的在所有的主流的App Server上自动编译EJB,部署EJB,测试EJB,也算做到极致了。 由于App Server五花八门和EJB部署本身的高度复杂度的原因,Java的企业开发也是远远不如C#来的快捷和方便。 这些原因导致了有时候一个J2EE项目会比.Net开发周期长两三倍的现象。 说完了C#和.Net的优势,再说说不足: 1、.Net平台支持多语言从技术上和开发角度来说是噱头,这完全是一个阴谋。 从ISV角度来看,完全没有支持多语言的必要,难道做一个项目,不同的模块用不同的语言来实现有价值吗?反过来说,这是一个灾难。对于将来的维护的升级来说是一个巨大的灾难,用VB.Net写的模块,C#程序员改不了,用C#写的模块,J#程序不能维护,人为的造成了混乱。再说C#又不是什么很难的东西,学习曲线也不高,何必不用C#,非要和自己过不去呢? 支持多语言的唯一目的在于吸引其它语言的开发人员转到.Net平台上来,不过当你被吸引转过来以后,还是发现用C#比较好,用你原来的移植语言不爽,还是不得不重新学习C#,这才发现上了大当了。所以完全是一个商业阴谋。 2、.Net在将来也不可能支持其它操作系统平台。 在前面已经提到了.Net和IIS,MTS,SQL Server等MS平台软件捆绑的很死,将来还要捆绑更多的MS软件,像IE,MSN等等。况且.Net依赖Windows也非常紧密。虽然有一个Open Source的Mono项目在移植CLR到Linux上来,不过据我来看,也只能做到仅此而已,光把CLR移植过来是没有多大价值的,需要把IIS,MTS,IE,MSN,SQL Server等等软件统统移植过来才能构成一个Linux平台上的.Net,但是这可能吗? 所以MS开放C#语言和CLI的规范又是一个商业阴谋,表面上装出一副拥抱开放的姿态,骨子里面却垄断的很。而且从MS的商业行为也可以看出这一点,我们知道MS把全部身家都压在.Net上和J2EE阵营竞争,如果.Net是一个开放平台,可以自由移植到Linux上,那么MS有什么理由不支持Linux操作系统呢?如果Linux上的.Net 支持的很好并且普及开来的话,J2EE恐怕只有在AIX和Solaris上苟延残喘的份了。正是因为MS要把.Net锁定Windows,所以才害怕Linux,如果Linux在服务器市场击败了Windows,那么.Net也只剩下苟延残喘的份了。所以现在MS视Linux为眼中钉,肉中刺。 所以MS开放C#和CLI,除了做作姿态之外,也可以在更多的OS上普及C#编程的教学,等你们熟悉了C#编程,再乖乖的在我的Windows上替我开发吧。 3、.Net傻瓜相机 众所周知,C#和.Net的学习曲线比Java和J2EE平坦的太多了。C#学习比Java轻松很多,而.Net框架学习比J2EE轻松太多了。那么Java程序员投入多了几倍的时间和精力就完全没有价值了吗?况且从开发角度来说,同样的项目C#也要比Java周期短,程序员开发轻松很多,难道这个世道对Java程序员这么不公平吗?没有理由下的功夫少,却得到同样的收获,所谓世上没有白吃的午餐。 经过我对C#和.Net的粗浅研究,我发现其实这是一个傻瓜相机和专业相机的问题。MS做出来的.Net的好学,易用,就如同傻瓜相机一样,一按就OK,不过照片质量一般。专业相机麻烦是麻烦,不过经过专业人士的手,拍出来的都是高质量的照片,当然你让普通非专业人员去操纵专业相机确实太勉强了一些。 .Net傻瓜相机确实太方便了,方便到了对组件的管理都对程序员透明化了。数据库缓冲池是由OLE DB Driver自动管理的;组件的管理是由MTS自动管理的,程序员不需要去管这些中间层的问题,开发好组件,用GAC注册一下就好了,使用的过程中,由.Net平台的MTS等等实际上完成App Server功能的服务自动处理。.Net Framkwork Configuration配置工具也是如此的简单,都是MS在帮你代劳。在运行.Net程序的平台上注意一下dllhost.dll这个进程,就是专门管理组件的。 不过从反面的角度来看,开发人员丧失了对组件部署的控制能力。在J2EE的世界,EJB或者说J2EE部署者是一个很重要的脚色,绝对不是可有可无,企业应用软件的运行性能很大程度上依赖对对于中间层组件的部署和性能调节和排错。所以EJB组件本身就是一个可以通过内部的XML配置文件参数进行性能自调节的组件,App Server更是提供了数量庞大,功能繁多的调节和部署选择。对于一个要求比较严格的企业软件来说,你要提供高效,稳定和安全的运行,手工进行复杂的tunning是必须的。对于只有一个全自动按钮的.Net傻瓜相机来说,实在是无能为力。 所以有所得就必有所失,.Net傻瓜相机在赢得了大部分普通程序员的同时,仍然无法进入企业高端领域,或者至少在目前是如此。不过不排除将来有这个可能性。 再看J2EE,EJB确实笨拙,开发起来速度也慢,但是一个构造良好,设计合理的J2EE应用经过高手的tunning,绝对是稳如磐石,令人放心。其系统的质量也不是目前的.Net所能比的。 说到这里觉得很有趣,MS从开始到现在,几乎所有的软件产品都在充当傻瓜相机的角色,就是到了.Net,MS也没能改变宿命。 Windows vs Unix SQL Server vs Oracle .Net vs J2EE 所以我敢断定,将来J2EE和.Net的处境也会类似今天服务器市场的Windows Server与Unix,数据库市场的SQL Server和Oracle。普通应用会更多的采用.Net,而高端应用更多采用J2EE。另外.Net还有一个不利的因素是J2EE虽然好像阳春白雪,其实下里巴人。J2EE既可以采用昂贵的商业App Server和DB的强强组合,也可以采用完全不要钱的免费方案,用成本来冲击低端市场,所谓各有各的活法。这也是MS比较头疼的。 4、分布式领域的不成熟 这体现在几个方面: (1) 分布式应用的Session管理 .Net的方案是几台App Server把全局Session放在一个共享的SQL Server中,实在是...笨拙,不用再评价了! 好好学习一下Weblogic集群的内存复制技术吧!.Net还差的远呢 (2) .Net的分布式组件 MS的DCOM已经过时了,让我们看看在.Net里面如何实现分布式组件。 首先在.Net中,普通组件和分布式组件是不同的,在编写代码的时候采用的方法就不同。一般组件类似于J2EE中的普通类,分布式组件要采用TCP Channel或者HTTP Channel来实现,完全两种不同的编程模型,MS建议采用HTTP Channel,因为可以穿越防火墙。而对于J2EE应用来说,一般商业组件都采用EJB编写,分布还是不分布,区别只是部署的时候放不放在一台机器而已。我没有仔细研究过TCP Chaneel或者HTTP Channel,不便于和EJB做对比,不过感觉上,这种Channel的可编程性和可管理性比EJB还差得远。 (3) XML Web Services .Net 上的Web Services加了一个耐人寻味的XML,什么原因大家体会一下。.Net的Web Services实现要靠IIS的ASP.Net,把组件以asmx的后缀放到IIS的Web目录下,当通过浏览器第一次访问的时候,Web Services自动编译和发布,同时生成WSDL。编程起来倒是好方便,但是我隐隐约约的感觉到MS的Web Services方案另有用意。什么用意呢?联想到第(2)点,我觉得MS的XML Web Services是DCOM的替代品。也就是说MS没有想到一个更好的解决分布式组件的方法,既可以容易的使用C#编程,同时又很容易部署,很容易进行分布式组件调用。万般无奈之下,在上面的Channel方案之外,又搞出这个XML Web Services,其实就是MS的分布式组件而已。但是HTTP SOAP调用的效率和安全性目前还比较差,还不能和EJB调用相比。况且XML Web Services仍然没有解决可管理性的问题,Web Services的性能调节看来只能靠IIS了。看看吧,EJB确实够笨拙,但是可编程能力,可管理能力,至今仍然是MS望尘莫及的。 所以就目前的.Net框架来说,MS还是暴露了在企业领域资历不够的弱点,Anders是程序语言设计的天才,设计了Turbol Pascal(也是我最早最喜欢的编程语言,在高一开始学习),Delphi和C#,不过他还不是企业领域的天才。 不排除.Net将来有赶上来的可能,不过目前J2EE在分布式领域还有很大领先优势,只不过Sun不太挣气了。 5、看似不错的Web Form Web Form也是我觉得很新颖的技术,甚至觉得很有前途,不过实际试用之后,我出了一口气,“不过如此” Web页面由于HTML的限制,表现能力很弱,于是Web Form技术出来了,就像GUI程序设计一样来拖拉控件来设计Web页面,好像很不错,其实问题也有不少。因为Web页面的设计和Web页面的编程是分离的,美工人员使用DW设计Web页面,程序人员嵌入代码。程序人员不负责Web页面的设计,如果都象Web Form这样,使用服务端动态生成HTML的表单元素的话,那么美工人员用DW一打开Web页面源代码,就会发现和在Visual .Net Studio里面的Web页面已经面目全非了。除非Web程序员把美工的活一肩挑,否则Web Form在Web程序员和美工之间的配合就是一个大问题。 6、C#的程序集还不够丰富 C#出来的时间比较短,而且因为出自MS之手,所以难以吸引大批的Opensource人员,目前Java的Opensource的类库极大的丰富,几乎所有你能够想得到的功能,一定可以在网络上找到某些人已经编写好的Java类库提供你来使用,这种优势也是很可怕的。C#目前达不到,以后也达不到这样的境界。 我对.Net的认识还很不够,J2EE vs .Net是一个热门话题,众说纷纭。在我粗浅的研究了C#和.Net之后初步的认为,从技术角度来看,如果你对J2EE已经非常精通了,那么目前也确实没有必要转到.Net上,除非出于市场的需要,或者其它的什么商业因素。况且在企业应用领域,.Net还做得不够好,仍然有很长的路要走。未来将是.Net和J2EE共存的局面,就像Windows vs Unix一样,低端应用更多的采用.Net,高端应用更多的采用J2EE。 就个人而言,C#应该就是借鉴的Java,但同时又有一些改变,去腐存精。可能是由于C、C++的原故吧,我个人更喜欢C#更倾向于用C#了。 现在才开始学,对java和c#都不太了解,不过我以前是玩delphi的,所以对c#感兴趣(c#的创始人就是当年编写delphi的老大Anders Hejlsberg),凭借ms的庞大技术实力也许会有希望的,现在java开发工具中比较好的是jb,但据我所知,jb的核心开发人物Blake Stone也已经离开了,也许我是盲从吧,天知道,选定了就不要回头,还好,我门公司的客户主要是用windows的,呵呵 我个人觉得,高端的企业级开发应用,还是用J2EE(EJB)来做,C#在这方面不如Java成熟,除此之外,在其他应用上,C#和Java各有千秋了。就看你怎么用了。 这位兄台,C#才推出来几年?JAVA可是经过了十几年的发展才有这么强的。你不能指望刚出来的C#会有多少强。经过五六年后,谁更强,谁知道呢?我想MS不可能五十年内倒掉,五十年,可以做很多事情了........... 楼上的,JAVA是95年推出来的,才9年而已,哪来十几年,一推出来就轰动世界,你以为JAVA是这两年才红的吗,你看看96年的程序员考试题目,里面已经提到JAVA了,可是至今还没提到.net,.net之所以能推出来,是因为它有JAVA的设计思想作参考,而设计JAVA的时候又有什么作参考呢?JAVA有它的危机,不过这种危机不是源于它本身,而是源于SUN公司的处境,我相信.net有它的美好前途 ,但这种前途不是源于它本身,而是源于微软的雄厚实力,大家不是常说吗,跟着微软走没错,确实是这样,但这也反映出大家对.net与JAVA本身实力对比的担忧。 事实往往如此,这不是技术大赛,而是市场上的竞争,最后决定胜败的不光是技术。公司背景、商业手段、当前的市场地位等等等等。谁的综合实力强,谁就是最后的胜利者。ms和sun的综合实力相比的话。大家都知道谁强吧。也有可能最后变成了ms-Java :) 数据库读取图片地址 WEB 是潮流还是王道? 求一开源web html编辑器 就这点分全给了 急急!!!!!!!!!!!!! 如何实现只让一个程序运行一次,在它运行时,不允许再启动一个新的进程。 思归,版主们请帮忙:如何将6行的vb代码转成c#?---Acrobat sdk ,往pdf文件里写控件. 为什么我的第一句无法插进数据库access?请大家帮忙找一下原因 QQ记录保存 怎样删除DetaSet中得指定列 看了c#的语法书,现有个问题想请教.... DataList的问题 高高手请指教,什么是.src文件?
转 robbin CLR和JRE的运行机制的初步总结概念比较:
Java C#
byte code IL(字节码,中间语言)
jvm.dll mscrolib.dll,mscrojit.dll(虚拟机)
JRE CLR(运行环境)
JDK .Net Framework(开发框架)
package assembly(类库,程序集)
一、关于类库的版本管理问题 Java和C#代码运行要依靠其运行环境(JRE,CLR)和运行环境带的基础类库(C#称为配件或者程序集Assembly),此外还会有一些第三方的类库或者自己开发的类库。如果运行环境版本不一致,或者引用的类库版本不一致都会带来程序不能正常运行。比如一个Java程序是在JDK1.2上开发,如果在JRE1.4上运行,一般情况下可以向下兼容,但也有例外,有些GUI程序在JDK1.4上面运行结果很可能会不同。 JRE的版本管理 Java的解决办法是每个程序自己携带一套JRE。
我的机器上已经被安装了好多套JRE和JDK了(JDK包括了同版本的JRE,此外还包括有编译器和其它工具),它们分别是:
BEA Weblogic Server 7.0 自带一套 JDK1.3.1_02
我下载了一套最新的JDK1.4.1_02
JBuilder9自带一套JKD1.4.1_02
Oracle8.1.7自带一套JRE1.1.7
Ration Rose自带一套JDK1.3
DreamWeaver自带一套JDK1.3
6套JRE,每套JRE都被各自安装到不同的目录,不会互相影响。当在控制台执行java.exe,操作系统寻找JRE的方式如下:
先找当前目录下有没有JRE
再找父目录下有没有JRE
接着在PATH路径中找JRE
注册表HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\ 查看CurrentVersion的键值指向哪个JRE
最常用的是在PATH路径中找JRE,一般情况下,自己的程序运行之前都会先在批处理文件里面临时设置PATH,把自己用的JRE放到PATH路径最前面,所以肯定会运行自己带的JRE,不会造成版本混乱。 .Net Framework的版本管理 .Net Framework被固定安装在C:\Winnt\Microsoft.NET\Framework\v版本号\目录下,听说刚发行的.Net Framework1.1已经对1.0做了很多改进,也许在旧版本的.Net Framework开发的程序在往新版本上面迁移的时候需要部分修改。 JRE的基础类库 JRE自带的基础类库主要是JRE\lib\rt.jar这个文件,包括了Java2平台标准版的所有类库。和JRE的版本一致。 .Net Framekwork的核心类库 .Net Framekwork的核心类库被放置在C:\Winnt\assembly\gac\目录下,按照不同的名称空间放在不同目录中,不像JRE打成了一个包。并且可以同时存在不同的版本,例如:
某类库1.0版本 C:\Winnt\assembly\gac\名称\1.0\名称.dll
某类库1.1版本 C:\Winnt\assembly\gac\名称\1.1\名称.dll
这样做,虽然很灵活,可以随时把类库更新到最新的状态,但是很容易带来版本管理的复杂度,造成版本不一致。 JRE类库的查找方法和版本管理 JRE中由ClassLoader负责查找和加载程序引用到的类库,基础类库ClassLoader会到rt.jar中自动加载,其它的类库,ClassLoader在环境变量CLASSPATH指定的路径中搜索,按照先来先到的原则,放在CLASSPATH前面的类库先被搜到,Java程序启动之前建议先把PATH和CLASSPATH环境变量设好,OS通过PATH来找JRE,确定基础类库rt.jar的位置,JRE的ClassLoader通过CLASSPATH找其它类库。但有时候会出现这样的情况,希望替换基础类库中的类库,那么也可以简单的通过-Djava.endrosed.path=...参数传递给java.exe,于是ClassLoader会先于基础类库使用java.endrosed.path参数指定路径的类库。因此Java的版本管理是非常简单有效的,也许很原始,不过很好用,简单就不容易出错。(所以我很奇怪Eric Ramond为什么批评Java的类库管理机制,他还居然批评Java的接口,令人怀疑他对Java的了解程度) .Net Framework的类库管理机制 .Net Framework的类库管理机制相当强大和复杂,分为私有类库和共享类库。
私有类库就放在exe程序当前路径下,或其相对路径中,只有当前程序可见。
共享类库需要在GAC(Global Assembly Cache)中注册,注册过程比较复杂,首先要用工具生成公开/私有密钥对,然后结合密钥和类库版本号连编,最后使用工具注册到GAC中好以后,会被放在"C:\Winnt\assembly\gac\类库的名称空间\版本号\"目录下,不同的类库版本在注册的时候会按照版本号分开放置:
某类库1.0版本 C:\Winnt\assembly\gac\名称\1.0\名称.dll
某类库1.1版本 C:\Winnt\assembly\gac\名称\1.1\名称.dll 也就是可以同时存在一个类库的n个版本,至于在程序中用哪个版本,在程序的配置文件中声明,CLR会根据声明来调用相应的版本的类库。我觉得.Net实现方法未免太复杂了一些,将所有共享类库都塞到一个系统目录下,并且同一个类库还有n个版本,将来.Net第三方开发的类库逐渐丰富起来以后,.Net类库的GAC也会越来越庞大,会不会也搞得和Windows注册表一样难以维护?软件发布到服务器上的时候,类库要再注册一次,服务器会逐渐形成一个庞大的树状的GAC,GAC里面存放着组件的n个版本。试想经过一段时间之后,C:\Winnt\assembly\gac\目录会越来越庞大,有的组件甚至有n个版本都放在那里,你又不敢随便删除,不知道是不是有程序需要使用,我不明白MS为什么要把这么简单的事情搞到这么复杂?
综上所述,Java的版本管理方式简单而有效,C#的版本管理方式功能强大,不过是不是太复杂了?会不会搞成第二个注册表一样的东西? 二、虚拟机启动和加载类库的方式
Java的虚拟机启动和加载类库 在Console执行java.exe xxx命令以后,如前所述的寻找JRE,OS找到JRE目录,根据java.exe的传递参数,选择加载Server版的jvm.dll还是Client版的jvm.dll,然后加载jvm.dll,把控制权交给jvm.dll。 接下来,jvm.dll进行初始化,分配内存等等动作,然后在CLASSPATH路径中寻找class,找到class以后,寻找class中的程序入口点Main函数,然后从Main函数执行程序,在执行过程中,使用ClassLoader动态加载一系列引用到的类。当调用到native方法时,jvm.dll告诉OS在JRE\bin目录下寻找某某DLL文件,调入内存,于是实现了JNI调用。
.Net的虚拟机的启动推测 我对.Net的虚拟机的启动过程还一知半解,自己写了一些例程,并且用内存工具来检测观察,推测.Net的运行机制,先来抛砖引玉,请熟悉Windows平台编程的朋友指教。.Net有3个目录中的文件在执行的时候会被加载 1、C:\WINNT\Microsoft.NET\Framework\v版本号\
该目录下的mscorlib.dll,mscorrsn.dll,mscorwsk.dll,mscorjit.dll是核心DLL,大概是运行虚拟机的必要文件,其中mscrolib.dll是入口点。此外,该目录下还有一些.Net的System名称空间的IL类库,与C:\Winnt\assembly\gac\相应目录下的IL类库完全一样,这些是最核心的基础类库。.Net的编译器,检查器等等工具软件也在该目录,推测System名称空间的核心类库之所以在这个目录下copy一份是因为作为.Net的编译器等工具的私有类库之用。 2、C:\Winnt\assembly\gac\
该目录下放置.Net共享类库,如前所述 3、C:\Winnt\assembly\nativeimages_.Net版本号\
在该目录下也有一些以System名称空间开头的核心类库,推测是MS为了加快CLR的执行效率把核心类库进行本地化,编译为native image的同名DLL。可以观察到该目录下的同名DLL文件,比GAC目录下的同名DLL文件体积大,可能是因为link底层DLL库的缘故。
某核心类库 C:\Winnt\assembly\nativeimages_.Net版本号\名称空间\.Net版本号_散列码\名称.dll 另外值得注意的地方是有两个mscorlib.dll
1、C:\WINNT\Microsoft.NET\Framework\v版本号\mscrolib.dll (1.88MB)
2、C:\WINNT\assembly\NativeImages1_v版本号\mscorlib\版本号__散列码\mscrolib.dll (3.07MB)
mscrolib.dll (1.88MB)还是一个IL码的版本,所以映射了一个native的版本的mscrolib.dll (3.07MB),来加快CLR的速度。
当IL的exe程序被双击执行时,OS Loader读入程序,识别出是IL,根据IL内部的引用定义,加载mscorlib.dll,而mscorlib.dll也是IL,内部引用C:\winnt\system32\mscoree.dll,于是再加载mscoree.dll,然后把控制权交给mscoree.dll,mscoree.dll接着加载mscrorsn.dll,mscrowsk.dll,mscrojit.dll,为了加快mscorlib.dll的调用,加载mscorlib.dll的native image版本,然后由mscorlib.dll接管控制权(不知道这两个mscorlib.dll是如何来上管IL,下连native code的?)最后寻找IL码程序的入口点Main函数,开始执行程序,在执行过程中,使用Class Loader动态加载一系列引用到的类,在当前路径下,在共享类库的GAC中查找等等。 这里和jvm.dll不同的一点是,jvm.dll加载的基础类库和加载其它类库方式完全一样,全部都是字节码的class。而mscrolib.dll加载以System名称开头的核心类库的时候,使用了“不正当竞争手法”。mscrolib.dll从GAC中加载共享核心类库之后,又C:\Winnt\assembly\nativeimages_.Net版本号\名称空间\ 目录下加载了核心类库的native版本,这样一来,自然CLR运行起来要快多了。特别是图形图像类库全部都有native映射版本,所以CLR上运行GUI焉能不快? 对比CLR和JRE的加载过程,比较不同的地方是mscorlib.dll和System核心类库都有一个native image,可能这是CLR运行速度比较快的一个主要原因吧。 分析完以后有一个特别明显的感受,Java的底层运行机制设计的特别简单,而.Net的底层运行机制设计的特别复杂。但是在企业层刚好相反,J2EE设计的特别复杂,而.Net却设计的特别简单,真是有意思! Java的底层机制设计虽然简单,但是很健壮,.Net设计使得它的CLR速度快,类库管理功能强大,但是不是比Java更优秀,还要等以后慢慢看了。
从ISV角度来看,完全没有支持多语言的必要,难道做一个项目,不同的模块用不同的语言来实现有价值吗?反过来说,这是一个灾难。对于将来的维护的升级来说是一个巨大的灾难,用VB.Net写的模块,C#程序员改不了,用C#写的模块,J#程序不能维护,人为的造成了混乱。再说C#又不是什么很难的东西,学习曲线也不高,何必不用C#,非要和自己过不去呢? 支持多语言的唯一目的在于吸引其它语言的开发人员转到.Net平台上来,不过当你被吸引转过来以后,还是发现用C#比较好,用你原来的移植语言不爽,还是不得不重新学习C#,这才发现上了大当了。所以完全是一个商业阴谋。 2、.Net在将来也不可能支持其它操作系统平台。
在前面已经提到了.Net和IIS,MTS,SQL Server等MS平台软件捆绑的很死,将来还要捆绑更多的MS软件,像IE,MSN等等。况且.Net依赖Windows也非常紧密。虽然有一个Open Source的Mono项目在移植CLR到Linux上来,不过据我来看,也只能做到仅此而已,光把CLR移植过来是没有多大价值的,需要把IIS,MTS,IE,MSN,SQL Server等等软件统统移植过来才能构成一个Linux平台上的.Net,但是这可能吗? 所以MS开放C#语言和CLI的规范又是一个商业阴谋,表面上装出一副拥抱开放的姿态,骨子里面却垄断的很。而且从MS的商业行为也可以看出这一点,我们知道MS把全部身家都压在.Net上和J2EE阵营竞争,如果.Net是一个开放平台,可以自由移植到Linux上,那么MS有什么理由不支持Linux操作系统呢?如果Linux上的.Net 支持的很好并且普及开来的话,J2EE恐怕只有在AIX和Solaris上苟延残喘的份了。正是因为MS要把.Net锁定Windows,所以才害怕Linux,如果Linux在服务器市场击败了Windows,那么.Net也只剩下苟延残喘的份了。所以现在MS视Linux为眼中钉,肉中刺。 所以MS开放C#和CLI,除了做作姿态之外,也可以在更多的OS上普及C#编程的教学,等你们熟悉了C#编程,再乖乖的在我的Windows上替我开发吧。 3、.Net傻瓜相机
众所周知,C#和.Net的学习曲线比Java和J2EE平坦的太多了。C#学习比Java轻松很多,而.Net框架学习比J2EE轻松太多了。那么Java程序员投入多了几倍的时间和精力就完全没有价值了吗?况且从开发角度来说,同样的项目C#也要比Java周期短,程序员开发轻松很多,难道这个世道对Java程序员这么不公平吗?没有理由下的功夫少,却得到同样的收获,所谓世上没有白吃的午餐。 经过我对C#和.Net的粗浅研究,我发现其实这是一个傻瓜相机和专业相机的问题。MS做出来的.Net的好学,易用,就如同傻瓜相机一样,一按就OK,不过照片质量一般。专业相机麻烦是麻烦,不过经过专业人士的手,拍出来的都是高质量的照片,当然你让普通非专业人员去操纵专业相机确实太勉强了一些。 .Net傻瓜相机确实太方便了,方便到了对组件的管理都对程序员透明化了。数据库缓冲池是由OLE DB Driver自动管理的;组件的管理是由MTS自动管理的,程序员不需要去管这些中间层的问题,开发好组件,用GAC注册一下就好了,使用的过程中,由.Net平台的MTS等等实际上完成App Server功能的服务自动处理。.Net Framkwork Configuration配置工具也是如此的简单,都是MS在帮你代劳。在运行.Net程序的平台上注意一下dllhost.dll这个进程,就是专门管理组件的。
SQL Server vs Oracle
.Net vs J2EE 所以我敢断定,将来J2EE和.Net的处境也会类似今天服务器市场的Windows Server与Unix,数据库市场的SQL Server和Oracle。普通应用会更多的采用.Net,而高端应用更多采用J2EE。另外.Net还有一个不利的因素是J2EE虽然好像阳春白雪,其实下里巴人。J2EE既可以采用昂贵的商业App Server和DB的强强组合,也可以采用完全不要钱的免费方案,用成本来冲击低端市场,所谓各有各的活法。这也是MS比较头疼的。 4、分布式领域的不成熟 这体现在几个方面: (1) 分布式应用的Session管理 .Net的方案是几台App Server把全局Session放在一个共享的SQL Server中,实在是...笨拙,不用再评价了!
好好学习一下Weblogic集群的内存复制技术吧!.Net还差的远呢 (2) .Net的分布式组件 MS的DCOM已经过时了,让我们看看在.Net里面如何实现分布式组件。
首先在.Net中,普通组件和分布式组件是不同的,在编写代码的时候采用的方法就不同。一般组件类似于J2EE中的普通类,分布式组件要采用TCP Channel或者HTTP Channel来实现,完全两种不同的编程模型,MS建议采用HTTP Channel,因为可以穿越防火墙。而对于J2EE应用来说,一般商业组件都采用EJB编写,分布还是不分布,区别只是部署的时候放不放在一台机器而已。我没有仔细研究过TCP Chaneel或者HTTP Channel,不便于和EJB做对比,不过感觉上,这种Channel的可编程性和可管理性比EJB还差得远。 (3) XML Web Services .Net 上的Web Services加了一个耐人寻味的XML,什么原因大家体会一下。.Net的Web Services实现要靠IIS的ASP.Net,把组件以asmx的后缀放到IIS的Web目录下,当通过浏览器第一次访问的时候,Web Services自动编译和发布,同时生成WSDL。编程起来倒是好方便,但是我隐隐约约的感觉到MS的Web Services方案另有用意。什么用意呢?联想到第(2)点,我觉得MS的XML Web Services是DCOM的替代品。也就是说MS没有想到一个更好的解决分布式组件的方法,既可以容易的使用C#编程,同时又很容易部署,很容易进行分布式组件调用。万般无奈之下,在上面的Channel方案之外,又搞出这个XML Web Services,其实就是MS的分布式组件而已。但是HTTP SOAP调用的效率和安全性目前还比较差,还不能和EJB调用相比。况且XML Web Services仍然没有解决可管理性的问题,Web Services的性能调节看来只能靠IIS了。看看吧,EJB确实够笨拙,但是可编程能力,可管理能力,至今仍然是MS望尘莫及的。 所以就目前的.Net框架来说,MS还是暴露了在企业领域资历不够的弱点,Anders是程序语言设计的天才,设计了Turbol Pascal(也是我最早最喜欢的编程语言,在高一开始学习),Delphi和C#,不过他还不是企业领域的天才。 不排除.Net将来有赶上来的可能,不过目前J2EE在分布式领域还有很大领先优势,只不过Sun不太挣气了。 5、看似不错的Web Form Web Form也是我觉得很新颖的技术,甚至觉得很有前途,不过实际试用之后,我出了一口气,“不过如此” Web页面由于HTML的限制,表现能力很弱,于是Web Form技术出来了,就像GUI程序设计一样来拖拉控件来设计Web页面,好像很不错,其实问题也有不少。因为Web页面的设计和Web页面的编程是分离的,美工人员使用DW设计Web页面,程序人员嵌入代码。程序人员不负责Web页面的设计,如果都象Web Form这样,使用服务端动态生成HTML的表单元素的话,那么美工人员用DW一打开Web页面源代码,就会发现和在Visual .Net Studio里面的Web页面已经面目全非了。除非Web程序员把美工的活一肩挑,否则Web Form在Web程序员和美工之间的配合就是一个大问题。 6、C#的程序集还不够丰富 C#出来的时间比较短,而且因为出自MS之手,所以难以吸引大批的Opensource人员,目前Java的Opensource的类库极大的丰富,几乎所有你能够想得到的功能,一定可以在网络上找到某些人已经编写好的Java类库提供你来使用,这种优势也是很可怕的。C#目前达不到,以后也达不到这样的境界。
我对.Net的认识还很不够,J2EE vs .Net是一个热门话题,众说纷纭。在我粗浅的研究了C#和.Net之后初步的认为,从技术角度来看,如果你对J2EE已经非常精通了,那么目前也确实没有必要转到.Net上,除非出于市场的需要,或者其它的什么商业因素。况且在企业应用领域,.Net还做得不够好,仍然有很长的路要走。未来将是.Net和J2EE共存的局面,就像Windows vs Unix一样,低端应用更多的采用.Net,高端应用更多的采用J2EE。
你不能指望刚出来的C#会有多少强。经过五六年后,谁更强,谁知道呢?
我想MS不可能五十年内倒掉,五十年,可以做很多事情了...........
公司背景、商业手段、当前的市场地位等等等等。
谁的综合实力强,谁就是最后的胜利者。
ms和sun的综合实力相比的话。
大家都知道谁强吧。
也有可能最后变成了ms-Java :)