Hello World
Spiga

Why Java Sucks and C# Rocks(2):基础类型与面向对象

2010-04-20 23:44 by 老赵, 12326 visits

既然已经谈过这次语言比较的意义与目的,而完整的幻灯片和录音也已经放出,那么接下来自然是详细讨论了。在这篇文章中,我会对两个语言的基本特征进行简单描述,并主要讨论两者对于基础类型的处理方式。在我看来,Java语言对于基础类型的处理方式,并不如C#中值类型般妥当。如果您有任何觉得不妥或是想要补充的意见,请不吝回复。由于C# 1.0发布于2002年,因此本文内容将基于Java 1.4及C# 1.0的情况。

Java语言简单描述

Java既是一个完整的平台,也是一门语言。Java语言是1995年由James GoslingSun Microsystems公司设计,作为Java平台的组成部分之一的语言。Java平台除了语言之外,还有两个组成部分,虚拟机(JVM)和类库。不过在这一系列文章中,我会将关注里放在Java语言这个单独的方面,偶尔会谈到一点JVM,而对于类库方面则几乎不会涉及。

Java语言参考了C语言和C++的设计,因此在代码整体风格上与它们比较类似。不过与C++相比,Java语言设计的更为小巧,简单和可靠。Java的类型分为两种:类(class)和基本类型(primitive type),并没有C++中的struct和union类型。同时,Java还提供了boolean类型,并对布尔类型的定义和使用作出了限制。此外,Java中也不允许开发人员进行运算符重载,但提供如synchronize等进行并发控制的语言特性。

Java语言设计的一大目标是可靠性,因此在Java中,部分元素的抽象级别被提高了,例如数组在Java中是预定义类的实例,在C++中就不是。此外,例如在数组访问中会进行下标范围检测,同时也去除了指针等不安全的语言特性。虽然Java中的“引用”也有些“指针”的意味,但更为安全,例如程序员不可以对指针进行算术运算,这样便避免了一些容易出错的做法。

在面向对象类型系统的设计中,Java不允许C++中的多重继承,因为许多人认为多重继承所带了许多复杂性和混乱,可谓弊大于利。不过Java允许开发人员定义“接口”,即一种“契约”而不包含实现,这在一定程度上也可以带来部分多重继承的优点。

总体而言,Java语言去除了C++中大量的复杂或是不安全的特性,这使的Java成为了一门灵活而强大,同时又更为小巧,简单和可靠的语言。从现在的角度看,Java语言大大降低了C++本身所带来的复杂度,让编程工作变的更为简单,具有很高的历史意义。

C#语言简单描述

C#语言是Anders Hejlsberg为微软.NET平台设计的一门语言。与Java语言不同的是,C#的定位只是.NET平台上各种语言中的一种——尽管如此,从现在来看,.NET平台和Java平台虽然起步不同,但可谓殊途同归。与Java平台比较类似,.NET平台除了多种语言之外,也有对应的虚拟机(CLR)及基础类库(BCL)。

C#的语言设计同样是基于C和C++的,但是也包括了一些Delphi和VB的思想。许多人觉得Java语言相比C++的优越之处在于“简单”,不过似乎C#的设计人员认为Java语言简化的有些太过了,因此C#将指针(受到一定限制)、struct、enum、运算符重载及goto等语言特性包含在C#语言中。不过,C#的设计人员同时也改进了这些特性,例如C#中的enum类型不能同整数类型进行隐式转换。同样,在C#的struct中,我们也可以为它定义构造函数和成员,并可以实现接口。

C#中还提供了一种数据类型“委托(Delegate)”,它可以被视为是一种类型安全的函数指针。一个委托也是一个对象,它明确定义了函数的签名,可以用来保存一个包含了调用时所需的上下文的函数。在.NET程序中,一个回调函数往往会使用委托进行表示,而在Java中,则一般会使用接口。

C#还提供了一些方便开发的特性,例如foreach,using,以及使用params定义可变长数组等等。此外,C#还提供了事件(event)及属性(property)两种对象的成员类型。属性可以简单理解为带有读写器(也可以只读或只写)的字段。Java语言虽然不包含属性,但很早便形成了一个约定,会将getXyz/setXyz方法作为属性处理,许多开发工具和类库都会以这种方式进行处理。

C#语言的初衷是要成为优越于C++和Java的通用程序设计语言。经过多年的发展,C#在语言设计方面的确遥遥领先于Java语言,这也是我写这一系列文章的事实依据。

Java是个纯面向对象语言吗?

Java在诞生于面向对象理论在业界愈发普及和流行的时期(著名的GoF设计模式一书便出版于1994年),在当时Java声称自己是个“纯面向对象语言”,但事实果真如此吗?我不这么认为,因为有很明显的一点是,Java语言中的基础类型不是对象。

在Java中定义了一系列基础数据类型,例如int,double,boolean等等。这些类型不是对象,它们不包含成员,也不继承于公共基类Object,因此Java并不是一门纯面向对象语言。

不过,其实我关注的并不是“纯面向对象”这个称号,我更关注Java语言在设计时是如何对待这些类型的。从代码上看,这个特点的确造成了诸多不便:

ArrayList list = new ArrayList();
list.add(5); // cannot compile
int i = (int)list.get(0); // cannot compile

int hash = 3.hashCode(); // cannot compile

上面这行代码有三处会编译不通过。ArrayList是个用于保存Object类型对象的容器,可以存放任何类型的对象。不过由于int类型的数值5不是对象,因此它无法被添加到ArrayList中。同样,在通过get方法获取到一个Object类型的对象后,我们也无法将其转换成int类型。自然,int类型没有成员,因此我们也无法通过它调用定义在Object类型上的hashCode方法。

直至Java 1.4,开发人员都必须编写这样的代码:

ArrayList list = new ArrayList();
list.add(Integer.valueOf(5));
int i = ((Integer)list.get(0)).intValue();

int hash = Integer.valueOf(3).hashCode();

在Java类库中也为每个基础类型分别指定了封装类(wrapper class),当遇到一些需要和Object进行互操作的时候,便可以把基础类型包装为一个对象。这些对象继承于Object类型,自然能够被添加到ArrayList中,也拥有hashCode等定义在基类中的方法。只是,在获取到Object对象并转换成封装对象时,还需要调用对象上的某个方法(如上面的intValue方法)才能重新获取到基础类型。

C#中的值类型

在此期间微软发布了.NET平台和C#语言。在C#语言中并没有所谓的“基础类型”,或者说C#的“基础类型”是作为.NET中的struct类型统一对待的。在.NET框架中定义了一系列struct类型,如Int32,Boolean,Double等等,在C#语言中使用关键字int,bool,double与之对应,这便有了一些“基础类型”的意味。自然,在C#代码中我们也可以直接使用那些类型的名称,完全等价。

开发人员可以在程序中定义自己的struct类型,并包含构造函数,方法或是属性等等,并统一继承于ValueType类型(值类型),而ValueType也是统一基类Object的子类。因此,在C#中那些“基础类型”也拥有Object类及自己的成员,并可以直接应用在需要Object的地方(即隐式转换)。因此,在C#中我们可以直接编写这样的代码:

ArrayList list = new ArrayList();
list.Add(5);
int i = (int)list[0];

int hash = 3.GetHashCode();

相信看了这几行代码您就能明白了。可以看出,在C#中,值类型和普通的类(也被称为引用类型)在使用上并没有任何区别。

当然,既然被称为“值类型”,它自然和普通的引用类型有所区别。首先,在.NET中值类型在赋值时是“整体拷贝”而引用类型只是复制一个引用。更重要的是,值类型是分配在方法的调用栈上,而引用类型则是分配在托管堆上。这意味着前者在当前方法退出后会被自动释放,而后者则必须等待GC运行时将无用的对象消除。

换句话说,值类型不会对GC造成压力(除非进行了装箱),这点很重要。在某些场景中,例如在并行计算时,假如每个线程临时对象创建地过于频繁,则可能导致GC频率加大。而GC在启动时会暂停运行中的所有线程,因此并行计算最终的瓶颈可能就落在了单线程的GC上——此时您投入再多的CPU等运算资源也无济于事。解决这个问题一般有两种办法,首先是启用并行GC,则为每个CPU分配一个独立的托管堆。在执行时,对象会分配在当前CPU的托管堆上,每个托管堆也有一个线程负责GC操作,这样GC能力也会随着计算能力加大而提高,因此不会成为性能瓶颈。另一种,有时候也可能是更为合适的做法,便是将创建的临时对象设定为值类型,这样一切便是在调用栈上的读写操作,便不会对GC造成压力。

在.NET平台中,一旦将一个值类型的对象用作引用类型时(即转化为Object类型或接口),运行时便会对它进行“装箱”:此时运行时会在堆上创建一个对象,并将值类型的内容复制到对象内部。将一个装箱后的对象转化为值类型时,则会将托管堆上的对象内容复制到方法的调用栈上,这便是所谓的“拆箱”。装箱和拆箱在.NET中是由运行时负责的,不需要特定的封装类,支持任意值类型。

在Java中,开发人员无法自定义值类型,因此所有的对象都是分配在托管堆上。不过这些倒也是和平台密切相关的内容,这里便只作一提吧,毕竟我们的目标主要还是在语言方面。

Java 1.5中的自动装箱/拆箱

Java语言基础类型和封装类型之间的这种转化方式,从1995年Java语言出现开始,一直保持到2004年Java 1.5出现才有所改变,将近十年时间。那么,Java语言究竟是因为缺少竞争对手而不思进取,还是因为没有比较就体会不到麻烦呢?无论怎样,我相信C#在这方面对Java语言产生的影响是毋庸置疑的。

不管怎么样,在Java 1.5中引入了一个新特性:自动装箱/拆箱(auto boxing/unboxing)。此时,我们便可以编写这样的代码了:

ArrayList list = new ArrayList();
list.add(5); // auto boxing
int i = (Integer)list.get(0); // auto unboxing

在int值5用在Object参数的时候,Java语言的编译器将自动生成创建Integer对象的bytecode。同样,将Integer类型的对象赋值给基础类型int的时候,Java语言的编译器也会自动生成intValue等方法的调用。那么,它和C#中的装箱和拆箱有什么不同呢?自然,区别之一在于C#的装箱和拆箱是.NET平台已有的功能,C#编译器只要直接使用即可,而Java的自动装箱和拆箱完全是编译器的工作。但我倒认为,这个区别并不是我这里特别关注的。

毕竟我现在关注的是语言,也就是通过代码本身所表现出来的,尤其是可以体现出两种语言在设计理念上有所不同的区别。

如果我们仔细观察代码的话,就可以发现,Java编译器其实是将Integer对象与int值互转,例如在上面的第3行代码中,我们先将Object对象转化成Integer类型,然后再隐式地转化至int基本类型。而在C#中,int类型是直接和Object类型相互转化的。我认为,Java的这种做法,表示Java的设计者依然不希望开发人员将int等基本类型看作是一种对象,他们只是让编译器可以帮助开发人员少些一些代码而已。换句话说,Java的设计者认为,int可以看作是Integer对象,boolean是Boolean对象,但是int和boolean仍然是基础类型,而不是对象。

下面的这行代码可能更加能够直接说明这个问题:

int hash = 3.hashCode(); // cannot compile

在Java中,这行代码是无法编译通过的,因为Java编译器并不会将int自动视作Integer对象,基础类型在这里依然是基础类型,不是对象。

在之前的讨论过程中,有朋友说,Java在这里不做自动装箱,是因为要在bytecode层面上保持与之前兼容。我不同意这个说法,因为我想象不到实现如C#这样的自动装箱和拆箱会破坏bytecode的兼容性,Java编译器完全也可以在语言级别将int类型和Integer类型等同起来,所以在这方面我认为完全是语言设计理念上的区别。

说实话,我不喜欢Java的思路,我更认同C#这种更为“面向对象”的设计方式。

相关文章

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

96 条回复

  1. 找不到
    114.225.190.*
    链接

    找不到 2010-04-21 00:42:45

    我看过了 占个楼先

  2. 找不到
    114.225.190.*
    链接

    找不到 2010-04-21 00:43:56

    咦 怎么没人评论?
    虽然还看不太懂 但是多看看还是学到东西的

  3. ariex
    202.161.13.*
    链接

    ariex 2010-04-21 01:12:33

    我猜后面一定有泛型……

  4. 老赵
    admin
    链接

    老赵 2010-04-21 01:33:28

    @ariex

    当然会有,我ppt不也已经放出来了嘛,呵呵。

  5. 链接

    鼠标也飞扬 2010-04-21 01:46:31

    虽然听讲座了,但还是想看看文章,哈哈~~~

  6. GuangXiN
    123.120.46.*
    链接

    GuangXiN 2010-04-21 04:36:19

    终于开始实质性内容的讨论了,千呼万唤始出来

  7. ok_008
    219.136.10.*
    链接

    ok_008 2010-04-21 06:50:35

    写的不错,关注

  8. Simcoder
    113.109.216.*
    链接

    Simcoder 2010-04-21 07:12:50

    赵老师要是能把.NET 的就业技术分块 就好了,比如做网站需要学习:C# ADO.NET ASP.NET 等 以致帮到一些入门后的人,并且给我们一个很好的指导学习路线

  9. 链接

    晓华 2010-04-21 08:13:03

    文章不错 受教

  10. 链接

    孝园 2010-04-21 08:25:50

    默默关注。。。

  11. _龙猫
    60.190.244.*
    链接

    _龙猫 2010-04-21 09:25:42

    老赵看起来有点怒了,哈哈.

    我不知道你是受了什么刺激所以想写这样的一批文章.我对Java不甚了解,来看这批文章是想为坚持C#增加信心的.在硬件资源允许的情况下,我一定会选择看起来更优雅的语言来写程序,即使它的性能稍微差点.

  12. 老赵
    admin
    链接

    老赵 2010-04-21 09:30:35

    @_龙猫

    我受到的刺激,就是居然许多人不知道Java语言现在已经落后于时代发展了,也不知道Java平台上有其他语言可用,呵呵。我写这批文章的目的已经写的很清楚了,您可以去看一下前一篇文章,不要臆断我的想法噢。

  13. deepnighttwo
    216.113.168.*
    链接

    deepnighttwo 2010-04-21 09:35:33

    Java一直以来都号称是纯面向对象的编程语言。这源自于Java语言的设计思想,其中很重要的一点就是万物皆对象。除Object类之外的所有类(class)都继承自Object类。Java编程语言提供了优秀而简洁的语法,让程序员在设计和编程时更容易的应用“封装、集成和多态”。久而久之自然就是以面向对象的思想来设计和编写程序的。

    我觉得,Java很具有魄力的将指针从语言中彻彻底底的删除了。在Java中不再有内存的概念,这是“一切皆对象”以及“封装”的彻底支持。只要是使用Java语言,就甭想着用个指针什么的窥探程序内部了,也甭想着用个指针玩什么花花东西了。因为一切皆对象,类型即封装。程序不能也不应该用一根指针在对象内部折腾来折腾去。想做什么事儿,让对象帮你来弄。如果对象不支持,那么这件事儿就是不应该做的。谢谢,对象内部闲人免入。

    说到这里就扯出了大名鼎鼎的swap。我见过无数玩C的人都对Java无法swap而对Java无尽的鄙视(准确点来说,是无法像C那样玩玩指针就能swap)。当然,我在这里就算说的再多,也是苍白无力的。。。我只想说一句:我写了这么久Java,从大到小从来没发现Java因为不能swap而无法完成某个task。

    当然,Java无愧于纯面向对象语言这个称呼,还有很多的例证,在这里就不一一列举了。

    说到这里我忽然想起来,C#语言一直让我觉得跟Java很像,很大程度上就是因为两门语言“神似”。这种神似源自于两门语言设计思想上的相同。不过,C#还是没有狠下心来把指针这个东西彻底的删除出语言。指针这个小东西,在我看来一直是面向对象的宿敌。说破了大天,我也不觉得对象内部的东西需要以任何一种方式,哪怕是受限的方式,而暴露给外部。

    运算符重载,这个东西见仁见之吧。对我来说一个copy方法调用要比一个隐藏着复杂操作的“=”更直观易懂。

    Java中有基本数据类型,这个基本数据类型不是类。文中说的这个是事实。个人的观点,对象是有代价的。对象是要在堆上分配内存的,是要通过垃圾回收来释放内存的。基本数据类型的“个体”在程序中的数量可谓庞大,如果全部使用对象的形式,可能会给垃圾回收带来很大的压力。而且,在这数量庞大的基本数据类型中,可能只有极少极少的一部分“需要”在程序中被看作是一个对象。于是乎,Java有了自动拆箱和装箱。不可争议的是,在这点上Java语言OO的纯度 < 春哥爷们的纯度。

    继续期待老赵yield。我确实也发现Java中多线程同步编程是有些复杂的。这是我闲着无聊写的一个小程序的演示:http://v.youku.com/vshow/idXMTU5MTY3MTEy.html 。里面用到了多线程并行运算。还是挺麻烦的。如果yield足够好玩,我打算写个C#版的玩玩。项目地址是:http://code.google.com/p/juliasetcreator/, 老赵有闲情逸致欢迎批评指正~

  14. 小羊肖恩
    218.106.184.*
    链接

    小羊肖恩 2010-04-21 09:39:00

    老赵有视频么?像PDC09那种,一边是PPT和演示,一边是演讲者。

  15. 老赵
    admin
    链接

    老赵 2010-04-21 09:41:30

    @小羊肖恩

    没有那么好的条件啊。

  16. 链接

    Lex 2010-04-21 09:42:49

    没去听讲座,报名晚了,遗憾啊

  17. 老赵
    admin
    链接

    老赵 2010-04-21 09:45:45

    @deepnighttwo

    其实C#的指针也不是可以随便用的,而是受限,且需要在unsafe块里,再配合编译器的选项才能使用,它的使用场景一般是用来做Interop或是一些对性能提高有帮助的地方,所以其实它的指针还是比C来得安全许多,呵呵。

    的确对象太多会给GC带来影响,因此我觉得.NET的做法还是相当靠谱,就是可以自己定义值类型。但它也是以对象的方式进行对待,这样既保证了概念上的统一,也可以保证较高的性能。

    yield一定会写的,您的程序我找机会看看,谢谢。

  18. Where
    121.62.124.*
    链接

    Where 2010-04-21 09:46:53

    老赵,你很棒...............

  19. SAY_NEVER
    218.1.97.*
    链接

    SAY_NEVER 2010-04-21 09:47:00

    首先是启用并行GC,则为每个CPU分配一个独立的托管堆 => 老赵讲的应该是SERVER GC吧

  20. 老赵
    admin
    链接

    老赵 2010-04-21 09:51:11

    @SAY_NEVER

    应该是吧,我忘了具体叫什么名字了,记得如果你写一个客户端程序,那么默认就是Workstation GC。

  21. mjo
    123.113.35.*
    链接

    mjo 2010-04-21 10:01:55

    别老跟1.4比,和1.5以后的Java比,田忌赛马一样,现在已经不是2004年了

  22. 链接

    sglicx23 2010-04-21 10:04:52

    @mjo

    java6带来了

    Nothing!

    Nothing!!

    Nothing!!!

    老赵的这段PPT给我的印象很深~~

  23. 链接

    diggingdeeply 2010-04-21 10:07:10

    我觉得C#里的指针还是太弱了,比起非托管里的指针。

  24. 链接

    Ivony 2010-04-21 10:08:18

    个人感觉上面两个Java程序员还活在十年前。

    首先,为什么要一切皆对象?

    3.ToString()和ToString( 3 )的不同在我看来便是OO思想最核心的部分。事实上OO从特性层面我们可以说有封装、继承、多态这三大支柱。那么是不是满足了这三者就是一个很好的OO语言呢?我看未必。考虑这样的伪代码:

    File file = fopen( "c:\test.txt" );
    WriteText( file, "Hello world!" );
    fclose( file );
    

    其实与

    FILE* fp = fopen( "c:\test.txt" );
    

    这样的代码又有什么太大的区别?能提高什么生产力?

    显然我们想要的OO是这个样子的:

    File file = File.Open( "c:\test.txt" );
    file.Write( "Hello world!" );
    file.Close();
    

    Java程序员一天到晚嚷嚷什么思想,没有干净的语法谈什么思想?!如果说OO改变了传统的面向过程的编程思想,其核心就是中缀函数表达式!如果像第一个例子那样写代码,又怎么去Thinking in Java或是什么OO或者C++。

    所以strlen(s)显然就是不如s.Length,同样的3.ToString()就是比ToString( 3 )要美。根本无需把Abs这种纯函数拿出来说事儿,函数和方法,是不同的两个概念。

  25. alonesail
    113.67.88.*
    链接

    alonesail 2010-04-21 10:12:44

    靠.net混的人.不否认C#是非常优美的语言,回退去写java确实是相当痛苦的事情. 老赵的角度个人感觉有些偏激. C#是Anders在搞了ms java后设计出来的语言,设计思想比java更高一筹那是顺其自然的事情;而且anders本来就是一个语言设计者而不仅仅是写编译器的coder其对不同语言的优良特性进行改良设计是顺其自然的事情. java确实很顽固不化.虽然高大爷等人创造性的设计出了java,但他们并不是典型的语言设计者,从历史的角度看java只不过是一件偶然事件.java已发展了10几年占据了n壁江山,在如此的情形下一群被人奉为神灵的高人是很难接受新的思想滴. 总会有爆炸性新闻爆出XXX搜索引擎是google杀手,不过很遗憾过没多久就销声匿迹了.如果C#是一个非盈利性组织研发而不是ms相信早在世界的某个角落里了.如果拿vb跟delphi比会发现vb的丑陋;如果把delphi跟java比较会发觉delphi不够面向对象;如果拿C++跟java等语言比较C++是勉强的面向对象而且复杂...但是他们各自有自己市场而并不见的XX杀手的出现就此消亡,因为有一大群人还要靠它吃饭.

  26. 1-2-3
    123.191.111.*
    链接

    1-2-3 2010-04-21 10:20:40

    非常精彩。Java应该是所谓“最小接口”的设计理念——越是核心的部分提供的功能就越少——这样就减少了语言(或虚拟机)设计者犯错的可能性啦,他们想的一定是,“这些花里胡哨的功能谁知道有多大用处,一旦提供了,以后可就收不回来了”。所以我们看到Java没有属性,想弄个回调还得先搞个接口,增加新特性也总是犹豫再三,也许真是给C++吓怕了,生怕一失足成千古恨。

  27. 链接

    Ivony 2010-04-21 10:22:21

    再来说说Java的贡献和指针的问题。

    尽管Java语言已经明显落后于时代,但Java对世界的贡献是不可磨灭的。从平台上来说,VM、IL、GC之类的东西就不必多言。从语言特性上来说,个人觉得,引用类型是最大的贡献(尽管我不知道这是不是Java首创的)。就语言层面上来说,C#的这个特性抄袭自Java是没有人能够否认的。但引用类型不代表我们就不需要值类型和指针了,这不是一个站得住脚的论点。如果在C#中没有指针,在牵涉到平台调用和native code互操作上面,就会造成很多的问题,直到今天,VB.NET或者除了C++/CLI和C#之外的.NET语言在与native code的互操作上都不如C#或C++/CLI方便。

    其次,一窥对象内部的结构,根本用不着指针这么低级的东西。Java平台另一个得到大家广泛应用的特性便是反射,这是一个让人又爱又恨的特性。反射大大的提高了静态类型语言的动态类型处理能力,但也使得反编译源代码变得非常简单了(不可否认IL也是帮凶之一)。无论如何从现在广泛的应用前景来看,这都是利大于弊的。回过头来,指针到底在C#中起到什么作用呢?就我这几年的C#实践来说,事实上MSIL在CLR上的效能并不比native code差多少,指针最大的用处还是在于动态内存分配、native code互操作和非托管资源(内存、对象、结构体等)访问上。在这些方面,指针的不可替代性其实很明显。

    上述中的IL意为中间语言,并不特指MSIL或是CIL,即同时也可以指ByteCode这种形式的东西。

  28. 果丹皮
    219.142.140.*
    链接

    果丹皮 2010-04-21 10:31:55

    @老赵

    既然你都把目的写的那么明确了,为什么非要惹JAVA程序员呢

    还不如对比JAVA 和 scala

    你明明说是想要java程序员转向scala因为java是落后的生产力

    却又非要在java和c#之间做对比 这就很难让人领会意图了

  29. 幸存者
    124.65.129.*
    链接

    幸存者 2010-04-21 10:32:50

    VM,IL,GC,引用类型这些东西都不是Java首创,Java的贡献在于把这些东西完美的结合(在当时那个时代)并成功的广泛应用在软件工业上而不仅仅是实验室里的玩物。

  30. 建议老赵用最新的C#和最新的JAVA比
    61.130.51.*
    链接

    建议老赵用最新的C#和最新的JAVA比 2010-04-21 10:38:11

    建议老赵用最新的C#和最新的JAVA比 建议老赵用最新的C#和最新的JAVA比 建议老赵用最新的C#和最新的JAVA比

  31. 链接

    麒麟.NET 2010-04-21 10:50:11

    很精彩,不过也很不过瘾,期待后续。。。

    // 独立博客的访问量还是不如博客园啊,这文章要是在博客园,早就4、5k了

  32. Jamesying
    116.228.133.*
    链接

    Jamesying 2010-04-21 10:50:34

    喜欢文章 更喜欢看评论 精彩啊

  33. abc
    117.84.26.*
    链接

    abc 2010-04-21 10:53:45

    精彩。 希望多比较一下语意层面的区别。 语法也很重要, 这样用户就愿意用, M$的软件销量有看涨。

  34. 老赵
    admin
    链接

    老赵 2010-04-21 10:53:59

    @mjo: 别老跟1.4比,和1.5以后的Java比,田忌赛马一样,现在已经不是2004年了

    -

    建议老赵用最新的C#和最新的JAVA比 建议老赵用最新的C#和最新的JAVA比 建议老赵用最新的C#和最新的JAVA比

    别急,会一直比到2010年,你让我比C# 1.0和Java 1.4我还不愿意呢,C#最经典的发力还是出现在2008年的,反而是Java 1.5以后基本就没什么变化了,呵呵。

  35. 幸存者
    124.65.129.*
    链接

    幸存者 2010-04-21 11:02:41

    另外,我不觉得OO的语法有什么过人之处。

    有人觉得 object.Method(argument) 的语法自然,可是搞数学的说不定觉得 function(x, y) 才好看。好比某种语法中国人觉得好,可是老外可能觉得很难看。虽说语法可以影响思想,但是语法的形式必竟不是本质的问题。

    老实说,我觉得单纯的OO已经很明显的落后于时代。因为OO从本质上来说还是基于冯诺依曼模型,而冯诺依曼模型天然不兼容于并行,想做到并行只能用增加中央处理单元这种低效而拙劣的手段。如果CPU工业现在的发展速度,在可以预见的将来基于冯诺依曼模型的CPU将会遇到物理上的瓶颈,这不是通过改进技术手段就可以克服的,而是必须改变计算模型。

    相应的,函数式语言可以看作对应于数据流计算机(冯诺依曼机相当于控制流),其并行能力远远高于冯诺依曼机,并且在工业上也有不少应用。虽然我们无法掌控硬件的发展,但是至少可以在软件编程上逐步转变。

  36. 链接

    Ivony 2010-04-21 11:04:31

    @mcpssx

    我可以肯定的说,10年后你能记住fopen,还能记住connect,send, recv,但是绝对记不住WCF是真么通讯的。

    所以说您还活在十年前,诚然十年后的今天我还记得fopen。但今天的程序员还用费力的记忆fopen或是printf或是atoi这样的函数么?这就是生产力的提升。

  37. 乱发吹风
    218.66.13.*
    链接

    乱发吹风 2010-04-21 11:07:06

    在面向对象语言的编程范式上,不建议在程序中直接使用基础类型,比如int,可以代表金额计算,可以用于库存统计,可以用于距离测量。但如果都只用int来实现,那就只能变量分别,这样很难清晰的找出哪个变量是金额或是库存。如果把它封装成类,并在类上加入值域控制判断,或者是跟业务逻辑相关的判断和方法,不是更好吗? 这会不会是Java语言所谓“纯面向对象”的初衷呢?

  38. 老赵
    admin
    链接

    老赵 2010-04-21 11:08:20

    @mcpssx: 为什么hashcode就应该是个方法,而abs就应该是个函数呢?F#中就有Array.len,注意是静态的函数。就算美了,也没有任何证据表明用s.length就比用strlen提高了生产力吧。

    我觉得你一直拿F#出来,这是个很大的问题。Java是面向对象语言,F#是函数式编程语言,它们从抽象方法,API设计方式上都是不一样的。你用函数式语言的理念,去说明一个面向对象语言也可以不做好面向对象,这我始终不能理解。

    当然,我同意说s.length不比strlen(s)生产力强多少,这篇文章倒的确在谈设计思路,还没有设计到生产力,以后会有更多关于生产力方面的内容的,呵呵。

  39. 老赵
    admin
    链接

    老赵 2010-04-21 11:09:19

    @abc: 希望多比较一下语意层面的区别。

    是,其实C#的成功之处之一也在于良好的语义,以后会有详述的。

  40. 链接

    Ivony 2010-04-21 11:14:04

    @幸存者

    另外,我不觉得OO的语法有什么过人之处。

    有人觉得 object.Method(argument) 的语法自然,可是搞数学的说不定觉得 function(x, y) 才好看。好比某种语法中国人觉得好,可是老外可能觉得很难看。虽说语法可以影响思想,但是语法的形式必竟不是本质的问题。

    每一种语言或编程范式都有其适用的场景,今天函数式在特定领域大行其道并不代表OO就没落了。商业模型很容易抽象成OO而不太容易变成函数式,就像算法很容易抽象成函数式,但把自然数当成对象并无助于我们解决算法问题一样。

    如果用离散数学的函数和运算的定义来解释加减乘除,就是一个大学生需要花点时间来理解,而这些东西却是小学生需要掌握的技能。但这并不代表离散数学就是把问题搞复杂的艺术,只是侧重点的不同。

    OO与函数式并不冲突,现在流行的语言多数揉合了这两者的特点(如C#、JavaScript)。在需要函数式的时候用函数式,需要定义对象的时候定义对象。如果你专注于“计算”,一个自然数后面点出任何东西对你而言都没什么意义。

  41. 老赵
    admin
    链接

    老赵 2010-04-21 11:15:02

    @幸存者

    FP的确显得越来越重要,尤其是在OO神话慢慢破灭,或者说淡去之后,现在FP又回到语言设计者的视线中来了。可以说函数式编程理念在影响目前所有的语言设计。不过我倒觉得,只要一天我们依赖冯诺依曼机,函数式编程就还是有天然的缺陷需要客服。

    此外,声明式编程角度看,FP一般都显得比较declarative。这也是C# 3.0所努力的地方。

  42. mrfangzheng
    123.124.143.*
    链接

    mrfangzheng 2010-04-21 11:17:09

    比较两个出生年代不太一样的语言 没什么意思 C#显然比Java有很多优势

    Java之于C++的变化可以说是非常大(至少main()的写法差别很大) 而C#之于Java只不过是一些小的改进而已

    对这2种语言我只想说, C#的delegate非常好用, 而Java的内部类则比C#简洁 其他对我没有太大影响

    和C++相比 就是速度有点慢 想不明白为什么WPF会用C#来写

  43. 老赵
    admin
    链接

    老赵 2010-04-21 11:22:46

    @mrfangzheng: Java之于C++的变化可以说是非常大(至少main()的写法差别很大) 而C#之于Java只不过是一些小的改进而已

    我会向您证明C#之于Java不只是一些小的改进(反倒不是指main的写法这类纯语法上的问题……),目前请先看一下我前一篇文章和幻灯片吧。:)

  44. Jeffrey Hua
    125.34.94.*
    链接

    Jeffrey Hua 2010-04-21 11:23:56

    It is hard to design a PERFECT language.

    The languages we are using reflect the designers' trade-off among many different conflicting forces during their evolution. This kind of shallow comparison is nonsense.

    Focus more time on understanding and solving your working problems.

  45. mrfangzheng
    123.124.143.*
    链接

    mrfangzheng 2010-04-21 11:25:41

    @mcpssx

    只针对Stream.

    Java的Stream区分了字节byte和字符char, 而fopen没有区分 如果认识到这一点, 在处理多语言文本的时候Java比C/C++省力多了

  46. 链接

    Ivony 2010-04-21 11:36:08

    @老赵

    FP的确显得越来越重要,尤其是在OO神话慢慢破灭,或者说淡去之后,现在FP又回到语言设计者的视线中来了。可以说函数式编程理念在影响目前所有的语言设计。不过我倒觉得,只要一天我们依赖冯诺依曼机,函数式编程就还是有天然的缺陷需要客服。

    此外,声明式编程角度看,FP一般都显得比较declarative。这也是C# 3.0所努力的地方。

    不太同意,在特定领域,例如描述算法,显然FP是表现力更强的形式。但这并不代表所有的领域都是。而这,还真是一个历史问题。FP并不是近期才提出来的新的概念,为什么近期如此火爆和流行,我觉得就像动态类型的流行一样,与当时的环境息息相关。

    那么FP为什么会忽然流行呢?个人以为原因有二。

    首先是VM和IL的大行其道,使得语言不必贴近于计算机硬件结构的底层。当初C语言为什么不设计成函数式风格,贴近底层我想是重要的原因之一。这是FP为什么能流行的必要条件,下面谈谈充分条件。

    我们发现在今天,算法不够用了,或者说今天的程序员不满足于预先定义好的一些算法和函数。想想传统的数据库开发我们写一个查询语句的过程是怎样的?首先写出查询的结构,然后去翻联机手册查查这里面的各个操作都是什么关键字,然后我们得到一个很Sucks的SQL语句,像这样:

    SELECT SUM( xxx ) AS sum FROM yyy GROUP BY zzz
    

    如果我们要求复杂一些呢?今天我们面对的查询需求多种多样,聚合的形式绝不仅仅限于SUM、COUNT之类,例如我们要查询每个分组里面数据的散列度呢?换作十年前,我们会组织一个科研团队,科技攻关,然后发明一种Extend SQL语法,增加了一个这样的聚合函数。好吧这很搞笑,因为现在是十年后,我们必须马上满足客户的这个需求,否则我们就拿不到订单收不到钱。

    所以,传统的function library模式破产了,我们经常会发现自己的要的算法在library中找不到,而一个越来越大的function library也带来了很长的学习曲线。大多数时候我们并不需要科学家为特定领域研究一种最高效的算法出来,而只需要一个,性能还能过得去的能解决问题的算法就可以了。

    所以,天生擅长描述算法的函数式在今天大行其道就不足为奇了。

  47. mrfangzheng
    123.124.143.*
    链接

    mrfangzheng 2010-04-21 11:40:50

    @老赵

    我的观点很主观 只从自己的使用角度来说

    我前几天看过 今天打开幻灯片速度太慢 我就不再复习了 我罗列一下我记住的新东西 - Linq - dynamic

    这些我目前都用不着, 周围用的人似乎也不多. Lamda只敢用最简单的, 复杂了自己都弄不懂 所以对于我来说, C#没有太大改进

  48. mcpssx
    59.175.192.*
    链接

    mcpssx 2010-04-21 11:44:35

    @mrfangzheng

    其实加个参数就解决了,c语言现在也有fgetws之类的东西。 java io有过度oo的嫌疑

  49. 老赵
    admin
    链接

    老赵 2010-04-21 11:49:11

    @Jeffrey Hua: The languages we are using reflect the designers' trade-off among many different conflicting forces during their evolution. This kind of shallow comparison is nonsense.

    我是基于现状进行比较的,的确语言的设计者在设计一门语言时会进行权衡,其实这些都是语言文化的一部分,讨论的目的便是展现出这方面文化,而不是说“避而不谈”就是没有意义的。此外我也没有避而不谈,只是可能我不太了解这方面文化,这就要由您来补充了,可以多说一些吗?

  50. 链接

    Ivony 2010-04-21 11:50:47

    @mrfangzheng

    我的观点很主观 只从自己的使用角度来说

    我前几天看过 今天打开幻灯片速度太慢 我就不再复习了 我罗列一下我记住的新东西 - Linq - dynamic

    这些我目前都用不着, 周围用的人似乎也不多. Lamda只敢用最简单的, 复杂了自己都弄不懂所以对于我来说, C#没有太大改进

    即使是最简单的,也能大大提升生产力。

    我们现在要做一件事情,从数据库中某个表例如xxx中取得所有记录的ID,按照yyy字段排序,然后在程序里面进行分页,然后再输出。考虑C# 3.0可以这样写(结合我的DbUtility数据库访问帮助工具):

    public IEnumerable<DataRow> GetData( int pageIndex )
    {
      return Context.DbUtility.ExecuteSingleColumn<int>( "SELECT ID FROM xxx ORDER BY yyy" )
             .Skip( ( pageIndex - 1 ) * pageSize )
             .Take( pageSize )
             .Select( id => Context.DbUtility.ExecuteSingleRow( "SELECT * FROM xxx WHERE ID = {0}", id ) );
    }
    

    更漂亮的形式:

    public IPagingSource<DataRow> GetData()
    {
      return Context.DbUtility.ExecuteSingleColumn<int>( "SELECT ID FROM xxx ORDER BY yyy" )
             .Select( id => Context.DbUtility.ExecuteSingleRow( "SELECT * FROM xxx WHERE ID = {0}", id ) )
             .ToPagingSource();
    }
    

    用法:

    <asp:DataBoundControl DataSource='<%# xxx.GetData().Page( pageSize, pageIndex ) %>' runat="server" />
    

    其中ToPagingSource是我写的扩展方法。

  51. 老赵
    admin
    链接

    老赵 2010-04-21 11:51:02

    @mrfangzheng

    如果您不去理解C#之于Java外的优势所在,那么的确C#比Java不会有多少优势了。我建议您适当了解一下,因为根据我的经验,我招聘来的3K/月的开发人员,也可以很快掌握这些内容并熟练使用,所以这些真不难。所谓磨刀不误砍柴功么,生产力提高是非常显著的,呵呵。

  52. 链接

    Ivony 2010-04-21 12:10:12

    @mcpssx

    你这个例子其实java也可以写出来,除了要用内部类。其实你想想看,jsp的displayTag不就是可以浓缩出来这个吗?

    就像用C也能写出来一样,C#不需要dynamic关键字也能用这样的语法来模拟动态对象:

    obj["PropertyName"] = "Hello world!";
    

    但有时差一点,结果就差很多。

    是的这都是糖,扩展方法完全可以用包装类么,lambda可以用接口么,这么多年了Java没有委托不也活得很好。但点点滴滴的麻烦积累起来,就可以阻碍新的思想产生。书写流畅是一件很重要的事情。

    Java的displayTag只能解决HTML层面上的问题,后面的这些肮脏的事情可没办法。不过ASP.NET的分层数据绑定模型可是非常强大的(可惜了解的人并不多。考虑这样的例子:

    <asp:DataBoundControl DataSource='<%# ((IPagingSource) Eval( "Posts" )).Page( pageSize, pageIndex ) %>' runat="server" />
    

    简单解释一下,Eval可以捕获“当前数据上下文”对象的属性。想想看如果这个当前数据上下文就是一篇博文。

    我们再考虑引入动态类型:

    <asp:DataBoundControl DataSource='<%# Data.Posts.Page() %>' runat="server" />
    

    好吧,Data现在是一个dynamic,当访问一个未知属性时,产生一个Eval( "PropertyName" )的调用,同时得到的Post也是一个dynamic,尽管它没有无参数的Page方法,我可以写一段代码使得Method miss机制开始寻找一个ParameterContext,从而正确的找到pageSize和pageIndex这两个属性的值绑定。

    最后,如果你像我这样把肮脏的事情都做好了之后,像Data.Posts.Page()这样的代码,有一点儿基础的IT专业用户自己都能写了。

    然后又会看到很多人说,90%的C#程序员只会写这种代码。。。。

  53. tang
    59.61.214.*
    链接

    tang 2010-04-21 13:15:30

    写的好,加油!期待下一篇

  54. 老赵
    admin
    链接

    老赵 2010-04-21 13:23:05

    @mcpssx: 你这个例子其实java也可以写出来,除了要用内部类。其实你想想看,jsp的displayTag不就是可以浓缩出来这个吗?

    Java不是做不到,Java很多东西都能做到,但都是做不好,做不容易,所以没人去用,不会形成一种开发思路和理念。一个特性只有真正自然好用了才易于推广开来。比如在C# 2.0中,匿名函数加上静态方法或是包装类也可以实现Ivony这种代码,但是直到C# 3.0引入扩展方法和Lambda表达式才把很多东西推广开来。

    我幻灯片里也有个例子,比如下面两段代码效果其实是一样的,首先是C#:

    List<string> keywords = ...;
    var result = keywords
        .GroupBy(k => k[0])
        .ToDictionary(
            g => g.Key,
            g => g.OrderBy(k => k).ToList());
    

    在Java中也可以做,例如有Functional Java类库,再配合内部类:

    keywords
      .groupBy(
        new F<String, Character> {
          public Character f(String s) { return s.charAt(0); }
        })
      .toMap(
        new F<Grouping<Character, String>, Character> {
          public Character f(Grouping<Char, String> g) { 
            return g.getKey();
          }
        },
        new F<Grouping<Character, String>, List<String>> {
          public List<String> f(Grouping<Character, String> g) {
            return g
              .orderBy(
                new F<String, String> {
                  public String f(String s) { return s; }
                })
              .toList();
          }
        });
    

    但开发人员真愿意写这样的代码吗?

    很多东西我以后会继续谈的,我会谈的很详细,也欢迎到时候再来讨论。

  55. Allen
    218.242.174.*
    链接

    Allen 2010-04-21 13:23:38

    object.Method(argument)要接近自然语法啊。比如computer.Open(file),这是完整的主谓宾结构,与英文语法相似。这个应该也算是oo设计的一个初衷了吧

  56. 愚兄
    207.46.92.*
    链接

    愚兄 2010-04-21 13:49:24

    很受用,期待下一篇快速推出!

  57. 链接

    Ivony 2010-04-21 13:53:18

    @Allen

    object.Method(argument)要接近自然语法啊。比如computer.Open(file),这是完整的主谓宾结构,与英文语法相似。这个应该也算是oo设计的一个初衷了吧

    正是如此,所以说中缀函数表达式是OO语法重要特色,由语法的变化,从而产生出My function和this的概念,这才进一步的衍生出OOD的思想。如果我们仅仅保留OO的特性,将语法还原为静态函数(过程)的方式。还能不能得到像现在这样的生产力呢?在这种语法规约下,要产生OOD思想和描述这种思想,恐怕都是非常费力的事情。

  58. gabry
    210.13.69.*
    链接

    gabry 2010-04-21 14:18:38

    windows不开源,c#永远没有前途

    1. 山寨你的c#程序
    2. 以C#他爹的名义用山寨你的产品来把你提出市场
    3. 在他的产品中集成山寨产品
    4. 在下一代的C#版本中,为山寨产品添加更多钩子,他的程序永远可以利用最新的C#特性

    网景怎么被微软搞定的?

    • NUnit VS Ms Test
    • NHiberate VS EF
    • NDoc VS Sandcastle
    • Log4net VS Logging Application Block
    • Castle Windsor/Spring.Net VS UNity

    这是一个什么行为? 一个流氓,假装你的声音,搞定你的老婆,在利用自己的权利,把你从家里赶走

    搞C#,你只能祈祷你的老婆不要太漂亮,被这位流氓盯上

  59. malimalihome
    59.59.6.*
    链接

    malimalihome 2010-04-21 15:28:56

    频繁的自动封装箱,无论是java还是c#,都会给GC带来沉重的负担。 java比C#更加面向对象,更纯粹(或者也可以被认为太面向对象而缺失灵活性),基础数据类型在c#中演变为结构体。 从楼主的本篇,完全无法提醒c#较之java的优势,起码我是不会认同的,期待后文。

  60. 老赵
    admin
    链接

    老赵 2010-04-21 15:37:13

    @malimalihome

    是,所以我觉得Java不提供.NET中那样的结构体来避免对象分配,在性能上应该也是有挺大影响的。

    Java比C#更加面向对象?我怎么觉得明显是C#把基础数据类型也视为对象了,这是更好的面向对象,不是吗?当然这里C#和Java的差距的确不够明显,这我一点意见也没有,呵呵。

  61. malimalihome
    59.59.6.*
    链接

    malimalihome 2010-04-21 15:51:47

    语言的优劣,并不是评价我们选择使用与否的唯一因素,楼主也提到了平台,类库,最终也会提到其在行业内的熟练程度,普及程度,学习成本,开发性,中立地位,进取力,同时还有编程领域和适用问题域。 太多的话慢慢再说,这里提一些学习java和c++的简单收获。 作者把c#和java作比,我想到了c++和c#作比,很多会是一样的效果,特别是在两组对比的前者超越后者的可控制性上,从对编程人员有更好的支持上,c#应该是好于java的,只是自始至终我都不认为那些有点脱离了语法糖之后能对语言的对比产生什么决定性的影响。没错,除了语法糖,c#还有许多真正从虚拟机级别上优于java平台的地方,这些特定从平台渗透到语言,使其强大,却没有到质变的程度。java不是落后的,相反,它才第二次被c超过(你明白第二次的含义),它在企业级应用和开源社区中的巨大影响,它在缓慢地变化,为留住编程人员既要缓慢又要变化,多说这些无异,老生常谈尔。

    楼主从c#的角度看待java,但有没有问问那些仍占编程市场主流的java程序员,从使用java多年的角度,看待java的发展。现在java应用已经饱和了,但在它饱和的领域主要并不是为c#所蚕食,它和c#其实是差异化竞争的,各自的应用领域正在拉开而不是同质化,楼主希望规劝大多数学java的人转到其它的方面,我不这么认为,我觉得大家应该首先从j2ee或java web走出来,不用急于丢掉java,它并不见得活不过c#。

  62. 老赵
    admin
    链接

    老赵 2010-04-21 15:58:08

    @malimalihome

    我觉得您还是看看我前几篇文章,了解一下我比较的目的会比较好。其实我也很希望有Java程序员可以来反驳我的看法,但首先还是要先了解我的看法,是不是?比如,我希望别人说,为什么他选择Java,而不是Groovy或Scala。但我希望他说,他选择Java,是因为Java平台总体上比.NET平台好,呵呵。

  63. 链接

    晓营 2010-04-21 18:49:03

    我是一个菜鸟,看了博主的的文章以及后面的评论,感觉视野开阔了很多 很期待后续的文章

  64. 老赵
    admin
    链接

    老赵 2010-04-21 20:10:24

    @mcpssx

    是的,这些都是可以讨论的话题,我现在的目的只是说Java语言设计糟糕,然后建议开发人员用Scala,我现在只是在比语言谁设计的好,并没有说用Java语言的人如何,更没有说应该去用C#,做项目自然要考虑更多东西,这不影响我的论点和论据。

    至于你说为什么用C#,而不是VB.NET或Boo,这些如果您感兴趣的话,等这个话题结束了我们再讨论,当然您也可以像我一样写一些东西,做一些呼吁,比如呼吁大家用VB.NET或Boo一样。

    当然我现在可以说我不喜欢用VB.NET,因为它的Lambda无法去除Function关键字,所以写不出漂亮的代码,而它在函数式方面相对于C#的优势,我没有遇到过所需的应用场景。其他方面C#和VB.NET差距不大,因此我留在C#里了。

    总而言之,C#和其他可选语言的差距,并不如Java与其他语言那样明显,所以我呼吁摆脱Java语言,但保留C#语言。

  65. Jimmy
    118.109.174.*
    链接

    Jimmy 2010-04-21 22:02:46

    看评论比看正文有趣。^_^

  66. gabry
    210.13.69.*
    链接

    gabry 2010-04-21 23:22:09

    后面的比喻错了,,,, 应该是,你盖了一栋房子,人家看上了,人家说,这是我的地,要么便宜把房子卖给我,要么房子拆掉 然后给你的房子粉刷一个新的颜色,打上MS牌

  67. crazycode
    58.32.208.*
    链接

    crazycode 2010-04-22 08:48:40

    gabry的比喻太精辟了!

  68. 老赵
    admin
    链接

    老赵 2010-04-22 09:33:24

    @gabry

    微软拆过房子嘛?最多重新造一个房子,然后铺天盖地打广告,抢了你的生意而已。

  69. 链接

    Ivony 2010-04-22 09:40:57

    @mcpssx

    这个仍然不是理由,现在大多数程序设计语言都是类C风格的,只要有C的基础,转换的学习曲线都不大。更不会影响到沟通,莫非我写的C#代码哪个Java程序员看不明白了?相信只用稍加解释,具备一定素质的Java程序员都能很好的理解Scala或是C#的语法。

    至于BOO和VB.NET,对前者不太了解不敢妄下评论。VB.NET之于C#和Java在语言风格上差异很大,这就好比要Java程序员去学Python或是Pascal一样。

    而最关键的问题在于,C#的表现力其实是足够的,我们假设C#从1.0开始便不再发展,一直原地踏步,而VB.NET则像现在这样突飞猛进,我想老赵这篇文章的标题改成Why C# Sucks and VB.NET Rocks也可以。。。。。

  70. 链接

    Ivony 2010-04-22 09:43:08

    照gabry的逻辑,.NET平台还只有微软一个拆迁办,Java平台有N个拆迁办的说。。。。

  71. 在青鸟上过课
    119.185.6.*
    链接

    在青鸟上过课 2010-04-22 22:29:04

    很精彩,学习! 内容和评论都精彩。

  72. Qualle2008
    77.6.5.*
    链接

    Qualle2008 2010-04-24 03:07:42

    "坦率地说,Java语言已经开始显示其年龄。Java的遗留将不再是Java语言,而是JVM和周围的生态系统,库已经长大了。Java是21世纪的Cobol语言,而这并不是一件坏事,只是一个客观存在的现象。"

    --- XXX ---

  73. shuhen
    222.173.95.*
    链接

    shuhen 2010-05-05 17:18:07

    评论非常有水平,比别处的口水仗要有意义得多,相当受教

  74. 老赵
    admin
    链接

    老赵 2010-05-05 22:46:21

    @mcpssx

    唉,你真的不了解C#,没有用C#编过程,居然说“XML比Where,GroupBy的场景要多多了”……我不想再针对你的主观臆断多说什么了。如果你想继续交流,拜托多找一些靠谱的理由来。

    还有你为什么还在说我是希望让Java程序员换平台,我说你是在故意忽略我阐述了无数遍的讨论目的么,这么讨论有意义么?我真的很难接受你这种近似无理取闹的方式了。Java表现力够么?你觉得够自然没有问题,不过我现在就在证明它“不够”,你等着看我下面的文章吧。

  75. 链接

    Nathaniel 2010-05-17 06:50:21

    程序员对语言的崇拜都不要太宗教了

  76. mt
    121.32.205.*
    链接

    mt 2010-08-04 08:50:48

    博主的技术文章写的挺好的,行文也很流畅。

    但是这篇文章我非常不喜欢,因为博主带有明显的语法和思想歧视。

    博主可能是做技术太久了,有点老学究了。这种比较不同语言差异的文章,就像比较中文和英文,或者比较苹果和梨子一样,几乎没有现实意义。每种语言都有各自的历史传承、文化以及当代现实,因此,我个人认为,比较语言最好的角度是社会学角度和历史学角度,而不是技术角度。

    如果你们是学校的老师,为提高学生上课的积极性,这种语法的比较倒不失为一种煽动的方式; 如果你现在在公司上班,把你的文章跟你老板分享一下,你会自讨没趣的!谁关心呢,关键是要赚钱?

    有些程序员动不动就“生产力”,动不动就要“漂亮语法”,这些单词用来修饰一门语言非常苍白, 你能说 中文的“生产力”比英文“生产力“高多少?下次当你准备要说 java or C#生产力如何如何的时候,想想前面那句话。

    好了,得罪了,但是实在是看不过去了,大家赶紧工作吧。

  77. jason
    119.6.78.*
    链接

    jason 2010-08-04 12:04:24

    @老赵: 在Java中,开发人员无法自定义值类型,因此所有的对象都是分配在托管堆上。

    老赵,你确定是这样的吗?我记得看JAVA编程思想的时候,那里面说JAVA的基本类型也是在堆栈上分配的,这点和C#类似。

  78. 老赵
    admin
    链接

    老赵 2010-08-05 19:42:37

    @jason

    你说的就是我说的,Java里就几种基本类型,我说的是“自定义的类型”。

  79. talentzxf
    61.171.198.*
    链接

    talentzxf 2011-10-25 23:22:37

    比较语言没有意义,各有各的应用场景~~~

    比如,.NET的运行平台我就憎恨。我碰到过一个朋友,做了一个非常简单的功能(就三五个form),非逼着用户(WinXP系统)装.net。程序就那么3M,.NET平台有 好几百兆,还得重启N遍。你说这有意思吗?

    Java就小得多了。

    实际上,我个人觉得 对于一个现代语言来说,能否支持更多的OS (Windows各版本,Linux)和平台(各种手机等等),有没有更好的类库,社区是否足够开放,文档是否丰富等等因素,远比某几个语言特性用起来是不是舒服要重要得多!

    这也是为什么C还有这么多人用的原因之一(应该比C#多吧?)

  80. 老赵
    admin
    链接

    老赵 2011-11-05 22:12:57

    @talentzxf

    我没说其他方面不重要,我只是说Java在这方面差太多了而已。说各有各应用场景这种套话实在没意义,尤其是Java和C#的场景几乎一致,C#有什么特征是“反Java平台的应用场景”的?

    还有啊,Java真不小,.NET真不大,现在.NET 4的Client Profile也就29还是39M的。

  81. RobinHan
    124.42.38.*
    链接

    RobinHan 2013-06-03 16:10:23

    我觉得有一点老赵没说, c# 的操作符(int)同样不能等同于理解为对象, 而是靠诉编译器,在编译的时候 根据平台(例如32位或64位)才转换成真正的对象 Int32或Int64, 在这一点只单独说int这个操作符的话,c#根java是很象的.

  82. 老赵
    admin
    链接

    老赵 2013-06-03 23:51:57

    @RobinHan

    你理解地一塌糊涂……

  83. RobinHan
    76.164.231.*
    链接

    RobinHan 2013-06-07 00:06:42

    请解释一下 为什么我理解的不对 我说的是从书里来的你认为int 是代表类吗? Int32 等同于 int ??

  84. 老赵
    admin
    链接

    老赵 2013-06-07 20:40:32

    @RobinHan

    请自行学习……

  85. 链接

    Hill Mark 2013-07-09 13:20:42

    老赵不屑于回答,我来回答吧,c#里面的int就是Int32, 看看编译后的MSIL就知道啦, 根本就没有int的影子了。int作为基元类型,可以让编译器高亮显示。 另外,没想到,这个post的comments从三年前一直延续到现在, 看来语言之争真是一个永恒的话题。

  86. 链接

    Cherry 2013-09-24 15:34:28

    OOP的思想本身没问题,但是有一点语法规则我觉得不好了,就是连枚举都成了类,使用枚举常量还得重复写上枚举类名,这个是徒增麻烦。。

  87. 链接

    isee 2013-10-07 16:37:51

    加入自动装箱/拆箱无非是让编译器帮忙 少写部分代码。

已自动隐藏某些不合适的评论内容(主题无关,争吵谩骂,装疯卖傻等等),如需阅读,请准备好眼药水并点此登陆后查看(如登陆后仍无法浏览请留言告知)。

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我