Java与C#的比较学习记录

我在大学学的是C语言,自学和选修的是C++,刚毕业也搞过几天Jsp,写过几个Applet.后来转向delphi做桌面开发,再后来又转向C#做Web开发.最近相对比较闲,决定学习一下Java,以取长补短,经过半天的忙碌,终于搭建起了开发环境,在网上找了一篇入门的教程,经过几个小时的练习(严格说叫复习),基本熟悉了Java的语法和基本的结构.在这里对Java和C#做些简单对比:
1) 历史
     Java当然比C#长,而且Java脱胎于C和C++,是典型的C风格,C#也是脱胎于C和C++,但由于C#晚于Java,也借鉴了很多Java的东西(C#之父Anders Hejlsberg)其实也是微软VJ++的主要架构师),另外,由于C#之父也是Delphi之父,因此,C#的体系架构不可避免的带有Delphi的VCL(代码是开放的,是我学习编程受益最多的地方)的影子.因此,单纯从语言上来说,可以这么讲,C#是C系列的集大成者,也是高级语言中的集大成者。
2)语法和风格
     都是C风格,书写上都差不多,至于花括号的摆放,那只是一种习惯。基本的语法,除了一些细微的差别外,两者基本相同,下面是一些差异比较:
     A)类和接口的继承和实现:C#都采用符号":"来表示,Java采用关键字"extends"和"implements"
     B) 访问限定,Java的default等于C#的internal,其它都是一样的。
     C) 常量:Java没有const关键字,一般用final达到类似的效果,在这方面C#有readonly,const等关键字,控制上更为灵活一些.
     D) 在类的多态方面:由于Java没有C#的virtual和override关键字,在表达上没有C#细致和明确。Java的公共,保护,缺省方法默认都是虚方法,所以Java比较容易实现动态注入(Spring技术),C#的访问安全控制性要灵活很多,但这个也有不好的地方,就是你想动态注入得时候,可能由于不是虚方法而无法注入。
     E)静态方法:C#的静态方法是不能继承的,而Java的静态方法是可以继承的(但不能重写,只能覆盖).由于静态方法和属性是属于类本身的,因此我觉得静态方法的可继承其实是没有必要的,而且不利于程序逻辑的管理。
     F)基本数据类型:基本的一些关键字都相同,但C#的多一些,具体的对应这里就不说了,这里特别记录一下的就是:Java中的int和Integer是有区别的,涉及到基本类型的装箱和拆箱,但需要特别注意,Integer是当作引用类型的,比如Integer i1=300,i2=300; i1和i2是不相等的,但Integer i1=100,i2=100; 中i1和i2是相等的,区别就是超过255比较就是不等的,而C#中int和Integer是没有区别的(至少在行为上),C#中的装箱和拆箱是与object相关的,虽然性能上有差别,但从基本数据类型的行为上来说是没有差别的。
           另外,C#中为基本类型增加了可空类型,这个估计跟java的引用基本类型类似。
     G)对象清除:机制都差不多,Java中的finalize和C#的dispose效用相当.
     H)异常机制:两者一样。
     I) 数组:C#分为两种数组类型,一种是普通数组,一种是锯齿数组,但java中没有区分。
     J)泛型:都来自于C++的模板类和模板方法,用法都差不多就,不过具体细节上估计会有差异,这里还没深入了解,不做断言;
     K)流程控制:有差别的是switch,Java沿用了C++做法,分支可以重叠,但C#要求每个分支都必须有break.从防止出错上来说,C#比较好,但不可避免的会失去很多技巧性写法和灵活性。

 

1) I/O:这个东西其实比较没什么意义,不过java的流概念跟C#的流概念其实都差不多,继承体系都差不多,只是Java中是Input,Output,而C#中是Read和Write.其实各自支持类中的方法名大部分都相同.当然,C# 除了流支持外,还兼容原来的一些文件读写.
2)序列化:对象的序列化两者都有支持,做法都差不多,当然,C# 中除了二进制序列化外,还可以序列化成XML格式(Java中有不有还有待更进一步了解).序列化的用途其实也差不多(主要是RMI).
3)反射机制:两者的反射机制差不多,当然,在这个方面C#的要完善一些,还加入了元属性(Attribute)的概念(Java中有不有类似的东西,学到目前还没发现,Java中的注解在C#中应该是///表达的东西).C#的反射内在机制我比较了解,Java的就不是很了解。但这种东西在Delphi中很早就有类似实现,只是没有现在的C#这样完善。当然,delphi还是欠缺些,而Java和C#都足够用。
4)多线程:这个其实是与语言无关的东东,不过在Java和C#中基本的实现方法还是差不多,类名都一样,只是方法名一个是run,一个叫Execute.Java中可以用Runable接口来简化线程的创建,C# 中是用方法和委托(包括Lamda表达式)来完成同样的工作.C#中的线程池(严格讲这属于框架而不是语言),后台任务之类的可以看作是一些二次封装的东西,没有对比的价值.
5)代码注入:C#和Java都是基于中间语言(C#的IL,Java的字节码),因此在实现代码注入上都比较方便,因此Spring中的面向方面的实现方法在C#中也很容易实现(可以参考我前面的博文).

6)重载:双方都支持方法的重载,而且规则基本差不多.为了简化这种重载C#中可以用参数缺省和params关键字来减少方法的个数,比如public void DoF(params object[] pms),调用的时候可以是DoF(p1),也可以是DoF(p1,p2...)等,这个在Java中是使用"..."来定义的:public void DoF(Object...pms).Java不支持参数缺省,参数缺省有其方便性,但不是必需(Delphi中很早就支持)。

7)委托和事件:这是带有函数指针,回调方法等味道的东东,找了一下,在Java中没有类似的概念,如果需要实现类似的东西,需要用到设计模式,比如观察者,代理等。C#,Delphi都有这个东西,这其实还是个非常好用的东西。我觉得Java完全可以借鉴升级一下(我查了一下,Java确实没有类似的东西,当然,也可能是我孤陋寡闻),Java没有这个可能是源于对纯面向对象语言的追求和对指针滥用的某种不安。
补充:经过查阅资料,Java中也有回调函数的实现,但实际上,这不是真正意义上的回调函数,只是一种模拟类似功能的东西.因为其传入的其实不是方法,而是类.从这个角度来看,我前面说的关于Java没有委托和事件的原因,估计是对的.

8)逆变和协变:其实只要是面向对象编程,存在继承就有这两种情况(方法的参数和返回值)。但大家只要把握一个原则:老子能用的地方儿子也能用,反之则不然。

 

总结:如果你对数据结构,操作系统,算法,面向对象编程等比较了解,其实相互转换还是比较容易的。做为苦B的程序员,完全没有必要为语言的排名而纠结,学习语言要有凌驾于语言层面之上的意识。

发布了155 篇原创文章 · 获赞 9 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览