.NET系列 第一篇 关于跨平台的种种言论之我见

说到.NET,就不能不提到跨平台这个很诡异的事实。.NET的跨平台和Java的跨平台说像也像,说不像呢,也不像。看起来都是在一堆库上面跑的代码,都是某种意义上的托管代码,但是实际上还是不一样的。

首先是能够用于开发的语言。.NET的VM制定了一系列的标准,为字节码做出了很多规范,并且提交成为ECMA国际标准。所有的语言都可以加入进来,只要你可以支持最低要求的CLR标准CTS,也可以生成IL字节码,如此便可。JVM其实也差不多,只要你的编译后的文件符合Java的字节码要求就行。

但是这里面其实是有一个比较大的不同点的。.NET提倡一个互操作的概念。也就是说,只要你是正式加入到.NET家庭里来的语言,都可以协同工作。比如你用COBOL.NET做一点数字计算的库,然后接口封装成CLR类型,就可以被C#等支持此类型的语言调用。简单举个例子,在CLR里面有个标准的字符串类型叫做String。而C#自身还有个字符串类型,叫做string。如果查看类型定义会发现,其实二者差异并不大。但是有个很关键的问题在于,string不是CTS成员而String是。所以只要是返回String的库,C#都可以用。其他的以此类推。

但是JVM在这个方面不是很提倡,所有的代码必须符合统一的规定,是属于全是全非的概念。最典型的例子在于,Groovy的介绍里说,可以编译成为JVM可以识别的字节码。这个意思就是说,Groovy支持JVM的标准。但是如果要自己有扩充,就会是一个比较麻烦的问题。同时,Java主要的库格式是jar,也就是一个包含特殊文件结构的zip文件。这种松散自由的文件格式也造成了JVM某种程度上的阻滞。换言之,所谓的jar不过是对一堆一堆的class文件进行压缩并规定或不规定入口点,仅此而已。

那么二者的不同点在哪里?最主要的一个问题,就是参与进来的语言的多寡。而造成语言多寡的一个最重要的原因,还是出在VM上。由于CLR允许一个编译器只支持一部分的标准,也就是你支持的标准集合是CTS的超集就可以,至于多出多少,那是后话,再议。而JVM的话,貌似没有这个讲法。这就给实现造成了很大程度上的不便。众所周知,Java是单继承多接口的一种语言,而很多语言支持多继承。其次,有的语言不支持OOP,有的不支持无符号数,各式各样的情况非常复杂。最简单的一点,如果想生成一个在JVM上跑的C++,估计会非常之困难。因为一个是单根继承,一个是多继承。

其次就是托管的力度上有差异。JVM在托管这个问题上依然是全是全非的做法。也就是说,你要么都是托管代码,跑在我JVM上,要么您就自己个玩去吧。而我相信做个C#开发的童鞋们应该见过一个Attribute,叫做DllImport,这个东西就是用来引入非托管代码的。一般来说,是在CTS实现的COM基础上进行互操作。虽然不建议这么玩,呵呵。Java里面也有类似的东西,叫做JNI。但是实际而言,用到JNI的几率不是很大,因为JNI调用的是系统相关的代码。

也许会有人问,DllImport和JNI都是调用系统库,都是去找系统相关的东西,这不就是一样一样的么。其实不然。

从微软的战略角度来说,他的想法当然是统一全宇宙大家都用我的Windows,这是很自然的事情。而在Windows平台上,第三方库的基本形式就是DLL文件,这文件其实是一个内嵌自描述清单的PE32文件。换言之,给它个Main函数,人家就自己个跑起来了。和EXE的唯一差别也就是木有入口点,就是一堆函数而已。在目前可以考察到的平台上,还有一种格式,就是so。也就是*nix平台。这种格式我没有做过深入研究,不过既然能实现和DLL类似的功能,那么自然也是有自描述清单一类的东西嵌在文件里。估计微软不管是放任MONO做大还是自己搞个虚拟机,都会根据这个情况来修改DllImport。

而JNI在某种程度上来说,由于Java的战略目标是彻底踢开OS,自己成为一个小的OS,所以难免在和系统底层交互的时候出现一些问题,或者说一些难题。这也是Java里有很多类似System开头的常量的原因所在,为了兼容每个系统的不同,不得不如此。最简单的例子,换行符。从ASCII角度来说,有的是10,有的是13,有的是10 13。我之前看过Mina的源代码,在状态机里有一段switch case。这段代码里罗列了windows,unix,mac以后,写了个default,也就是说默认情况。这其实是一种很不妥当的策略。也许,假设,某一天BEOS又重新恢复了活力,人家的换行符和您的不一样,您咋弄?这里虽然不是说批判mina这个优秀的Apache框架,但是这也是一个小小的问题。

说了这么多,总结一下吧。究竟.NET和Java的跨平台实现有什么不同呢?

其实两者在技术上相差无几,而且.NET实际上是在Java的基础上发展起来的。区别主要在于对待跨平台的实现方针上。.NET系列主要是扎根于每个不同的操作系统,做出不同的运行环境,所以可以实现一些特有的功能,而自己的程序员不用去考虑10 13之类的问题。而Java主要是方针是在操作系统上架起一层环境,剥离开每个系统的不同,实现一个大同世界,力图用自己的虚拟机来完全模拟操作系统。只是因为世界本不平,所以Java会出现不能Run Anywhere的局面。类似10 13之类的问题,还有其他很多很多的问题,导致了Java出现Write Once,Debug Anywhere的局面。

不能说Java不好,也不能说.NET一定优秀,孰优孰劣,交给时间去定夺吧。下次准备和大家谈谈关于.NET和Java在对待自己的程序员方面的一些不同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值