`
JeffreyZhao
  • 浏览: 11962 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

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

阅读更多

既然已经谈过这次语言比较的意义与目的,而完整的幻灯片和录音也已经放出,那么接下来自然是详细讨论了。在这篇文章中,我会对两个语言的基本特征进行简单描述,并主要讨论两者对于基础类型的处理方式。在我看来,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#这种更为“面向对象”的设计方式。

相关文章

20
25
分享到:
评论
29 楼 liudun 2010-05-22  
JeffreyZhao 写道
@ZHH2009

其他不多说了都说过很多遍了,我现在想说的是……

微软给技术人员带来了很多东西啊,就拿最新的来说,IronXxx,DLR,F#,Reactive Framework,Parallel Library等等。而且你说Java影响了C#,Scala的设计,其实新的语言比如C#,Scala,Groovy,F#等等基本都在互相影响,噢,还有Haskell被人参考了很多。.NET虽没有Java平台开放,但是可能也比您想象中来的开放吧,呵呵。

当然,这个技术社区可能的确不太争气,但是这些技术的质量还是相当好滴。Java平台不该死,但Java语言的确该死了……好吧,我是指退出历史舞台,放到神坛上供着就可以了,大家都用Scala吧,活活……


典型的技术人员思维。你可以跟全国人民说‘GSM已经out了,供着吧,换3G了’,看有百分之几的人鸟你?这是在市场经济而不是学院里,切换要成本。就算JVM上跑Scala比Java语言好,要普及也不是几年的事情。。。
28 楼 night_stalker 2010-04-28  
eclipse 可以先写 return,然后一步步往上在小红线上 ctrl + 1 用各种类型推断和自动 fix 造出代码 ……

可以写一个系列,书名分别叫:
《Eclipse Hacks:不看代码编程》
《Core Eclipse Hacks:面向红线编程》
《Even More Eclipse Hacks:面向黄线编程》
《Eclipsh:超越 Eclipse Hacks》
《Eclish:Eclipsh 的终结者》
……
27 楼 JeffreyZhao 2010-04-28  
RednaxelaFX 写道
接上前面xuwenhao的观点,放一个InfoQ老文的传送门:http://www.infoq.com/articles/evolving-java-no-lang-change

这篇文章我以前也看过了,呵呵。
其实我也和这篇文章评论里有些人的看法一样,为什么要用IDE为Java增加特性,而不是使用另一门语言呢?为什么javac就是不愿意改变,而IDE对Java语言的增强就不算是Java语言的增强了呢?这点我还是搞不太明白。
就像第一篇回复里说的:Is it really fascinating to see so many Java folks desperately fighting missing language features, while many others already look for alternative languages?
26 楼 Saito 2010-04-28  
night_stalker 写道
eclish is not java ……


  eclish => eclipsh.


  new speak的主旨其实就是 大家讲的都是eclipsh ..eclipsh有各种黑魔法..
25 楼 JeffreyZhao 2010-04-28  
xuwenhao 写道
赵姐夫认为语言特性造成了生产力的巨大差别,并且认为这些特性是无法依靠类库,框架,IDE来弥补的,我不这么认为。

所以,我觉得吧,你还是多花精力去创造点东西,或者分享经验,语言比较,其实对于大家都没啥用的


呃,这个用IDE弥补其实挺令我感到惊讶的,如果真一个IDE可以把Java语言辅助成C#,那么我也就满足了,呵呵。嗯,如果真的大伙儿都普及了Java这种方法,那么就没问题了。多谢您的建议,我这些文章最后的建议里,除了换成Scala,也会加上你这种的,呵呵。

至于你说有没有啥用,我还是保留自己看法啊,我现在就是在分享自己的经验啊,尤其是C#开发经验。就想你说的,许多程序员给它个Lambda都不会用,那么我就是分享一下Lambda该怎么用这件事情。
24 楼 night_stalker 2010-04-28  
eclish is not java ……
23 楼 RednaxelaFX 2010-04-28  
接上前面xuwenhao的观点,放一个InfoQ老文的传送门:http://www.infoq.com/articles/evolving-java-no-lang-change
22 楼 rubynroll 2010-04-28  
补充一个:在Ruby中函数可以返回多个值,这个也挺不错(算是模式匹配的延伸?)。
21 楼 xuwenhao 2010-04-28  
赵姐夫认为语言特性造成了生产力的巨大差别,并且认为这些特性是无法依靠类库,框架,IDE来弥补的,我不这么认为。

比如赵姐夫说到的lambda表达式,我google了下,在现在的java,你可以通过一个IDE的plugin来进行弥补:
http://code.google.com/p/lambda4jdt/

也可以在Eclipse写出来


或者


作为Java代码

(看了一下,显示没有问题,编辑后自动重新生成代码还不完善?)

完全可以满足赵姐夫的美学要求。

事实上,强大的类库+IDE完全可以弥补所谓的语言特性,事实上,对于大部分的特定领域的开发,在工作量大的情况下,都是通过类库和框架定义下的DSL进行开发。

对于Java,你可以选择使用Antlr来定义自身的DSL来做到。

对于使用者来说,这只是一个特性由编译器实现,还是类库或框架作者来实现的区别。
而作为开发者,后者你可以自己来实现,并没有太大区别。

从语言特性的角度来说,好的开发者不需要你来告诉他们,也会通过新的语言,类库,去尽量减少开发工作。糟糕的开发者,即使是C#,他也写得和VB没有区别。

事实上,Java语言的优势,就在于你所说的劣势,就是傻到暴,对于大部分Java开发者来说,他们所做的工作就是in-house开发或者外包开发,即使Lambda表达式放在那里,他们也不会去考虑。事实上,有时候你会怀疑,他们是不是只需要if...else,for循环对于他们都是多余。

所以,我觉得吧,你还是多花精力去创造点东西,或者分享经验,语言比较,其实对于大家都没啥用的

20 楼 JeffreyZhao 2010-04-28  
night_stalker 写道
其实我还想说:
Potion 跟 Ruby 比,就和 Ruby 跟 C# 比一样;再过几年,我还能写 Why Potion Sucks ……

支持你先写Why C# Sucks,像我一样仔细分析,呵呵。
19 楼 night_stalker 2010-04-28  
其实我还想说:
Potion 跟 Ruby 比,就和 Ruby 跟 C# 比一样;再过几年,我还能写 Why Potion Sucks ……
18 楼 JeffreyZhao 2010-04-28  
Saito 写道

既然要强调生产力高..那像Java.C#.Ruby这种"汇编".还是不要拿出来比较生产力高低了..

一种语言的生产力高低.跟他所属的环境与人是分不开的.生产力最高的语言是自然语言.所谓行业术语..(如果自然语言能被实现可编程).其次呢.. 不用我说了吧. 就是各种DSL. .再往下才是创造DSL的某种"汇编".以及创造"汇编"的汇编..

楼主用各种linq创造了自己的DSL .. 然后说你看C#生产力高吧..这不完全搞反了嘛..是你C#创造的DSL生产力高而已..

当然.martin fowler会在新书<<Domain specific languages>> 里面详尽阐述.. 其实所谓内部DSL跟外部库DSL本身就是很相近的..只谈语言.忽略所谓库..本身就是很扯淡的..

这样比较.按您的说法.Scala比Java生产力高是吧? ..那么你学习以及掌握的成本有多少?..更换一种语言.你的机会成本是高是低 ...都是需要计算的..

最后各种附上sinatra的各种WEB DSL(基于Rack) .. 简洁的令人发指.

 
require 'rubygems'
  require 'sinatra'
  get '/hello/:name' do |n|
    "Hello #{n}!"
  end


好吧.. 我承认这才是生产力高的语言.. 因为它不是"汇编".


那么,您可以认为我比的就是谁构造DSL的能力强吧,呵呵。我最近其实一直在宣传的是F#和Scala,它们都是对DSL构建有侧重的。就像您举得例子,不觉得其实就是说明Ruby的生产力高吗?忽略库的原因,是因为只要有需要,只要语言能力够,就有人可以实现出库来。语言和库相比,我认为语言是生产力更大的瓶颈……当然前提是真有人会写出库来,呵呵。

Scala比Java生产力高,学习掌握成本自然我也不否认,所以我一开始就写了,不会说应该立即切换语言,因为语言不是全部,是考虑的一部分。我强调的是,要从现在就开始接触Scala了,呵呵。
17 楼 Saito 2010-04-28  
JeffreyZhao 写道
五月天 写道
我不知道写这篇文章的作者的用意如何,不过显示有点偏重c#,可能是学c#的吧?
其实语言没什么可比较的,关键在于运用在什么地方,java也好,C#也好,只要能做出好的产品,都是好的。java和c#不都还在发展吗?java7出来后说不定会比c#更实用呢?且现在的ruby语言比上面的两种语言更人性化。所以没必要在语言级方面作什么比较~!
我也纳闷了:怎么现在老是有这样的文章出现。作者就没能写点其它更有意义的东西吗?

我觉得这个话题很有意义呢,国内从来没有过靠谱的比较,于是就由我来了。其实C#比Java的优势不在于功能多,而在于强大,生产力高,提供更好的编程范式及思维。Ruby的话,我不觉得比C#有多少优势啊,希望有人可以比较一下C#语言和Ruby语言的生产力,呵呵。

对了,我这次文章会一直比到最新的C# 4和Java 7的,结果就等我继续写咯。

 
  既然要强调生产力高..那像Java.C#.Ruby这种"汇编".还是不要拿出来比较生产力高低了..

  一种语言的生产力高低.跟他所属的环境与人是分不开的.生产力最高的语言是自然语言.所谓行业术语..(如果自然语言能被实现可编程).其次呢.. 不用我说了吧. 就是各种DSL. .再往下才是创造DSL的某种"汇编".以及创造"汇编"的汇编..

  楼主用各种linq创造了自己的DSL .. 然后说你看C#生产力高吧..这不完全搞反了嘛..是你C#创造的DSL生产力高而已..

  当然.martin fowler会在新书<<Domain specific languages>> 里面详尽阐述.. 其实所谓内部DSL跟外部库DSL本身就是很相近的..只谈语言.忽略所谓库..本身就是很扯淡的..

  这样比较.按您的说法.Scala比Java生产力高是吧? ..那么你学习以及掌握的成本有多少?..更换一种语言.你的机会成本是高是低 ...都是需要计算的..

  最后各种附上sinatra的各种WEB DSL(基于Rack) .. 简洁的令人发指.

 
require 'rubygems'
  require 'sinatra'
  get '/hello/:name' do |n|
    "Hello #{n}!"
  end


  好吧.. 我承认这才是生产力高的语言.. 因为它不是"汇编".


  最后.我又hello World .. . ..偶哇鲗..
16 楼 JeffreyZhao 2010-04-28  
RednaxelaFX 写道
老赵不是不满只见顶踩嘛,我就来参一腿了。你的博客那边自然不怕没人评论,有时间过去玩~


哈哈,不过我一会儿就擅自把你的评论转载到我那边去了,呵呵。
15 楼 RednaxelaFX 2010-04-28  
老赵不是不满只见顶踩嘛,我就来参一腿了。你的博客那边自然不怕没人评论,有时间过去玩~

JeffreyZhao 写道
@night_stalker

多谢您的认真评论,我其实希望的也是您这样的回复,我也回复一下啊。

1、模式匹配是好东西,不过很多情况下更像是简化了一点点开发而已,我第一篇文章里说了似乎并非我看重的东西,或者说你能不能多提一点它对开发模式的影响?

2、能用break,next的确不错,不过each比ForEach好看100倍实在没理解

3、没看出对于开发模式有什么影响,我觉得C#和Java也都可以实现,也并非不可接受。
至于你说object.is_a?(Klass)和object is Klass,Klass.new和new Klass()孰优孰劣,我实在觉得实在不算什么。

1、话说有些东西“只是简化了一点点开发”,其实同时也就是解放脑力。之前老赵已经见过这种Ruby代码了:
a, b = b, a

OK,这个我们可以在C#里自己写个Swap方法达到这种效果:
Swap(ref a, ref b)

假如实现Swap的时候我们用了中间变量,那这个中间变量就是我们需要操心的地方,是how;如果用异或来做整数交换,这更加是把直观的东西换成了hack的。
交换两个变量的时候,从调用方看倒不会有多少感觉,但如果是“错位交换”呢?
a, b, c, d, e =
b, c, d, e, a

可以很清晰的看出交换的对应关系,同时又不需要关心到底是“如何”交换的。要说对开发模式有什么影响,hmm,至少少一个对自定义方法的调用,可以少担心一些奇怪的副作用?

2、break、next与redo是Ruby非常重要的语言特性,特别是在block里用的时候,因为此时它们有“non-local control flow”的语义。这种特性实现起来也挺麻烦的,C#、JavaScript之类的C-like语言的匿名函数都不支持non-local control flow,而以前BGGA方案的闭包就是因为支持non-local control flow而被一大堆人说太复杂了。诶诶。

3、使用普通的方法调用语法就达到良好的视觉效果意味着程序员有更高的地位,因为完全可以写出感觉与内建库一样的新API来。类是对象这点也是Ruby(和Python之类)比C#/Java更加面向对象的地方。要说谁“更”面向对象或许还可以比比,不过要说谁“最”面向对象的话那就不好说了……我觉得prototype-based的对象系统还是更面向对象一些(看Self)。
14 楼 dennis_zane 2010-04-28  
对c#不了解,单纯说说Ruby让我感觉爽的几个地方:
1、open class,不用说,随时随地monkey patch
2、人性化的API设计,一个数组取长度可以用size,可以用length,你完全猜得到,不需要查API,这通过alias很容易做到
3、强大的元编程能力,从ActieRecord的magic可见一斑,反射API非常友好,比之java reflection不是一个档次。
4、模式匹配,在Erlang中的两个用途:数据结构的拆解和程序分支的实现,例如用在协议解析上,模式匹配显得直观,模式匹配就是一种DSL,描述结构并自动拆解,Ruby中能否做到?没试过。
5、each比ForEach好看还是很明显的吧,each显然更面向对象。
13 楼 JeffreyZhao 2010-04-28  
ZHH2009 写道
八卦一下:

Neal Gafter是身在曹营心在汉呀,目前还是Javac Team的成员。

傻时C#编译器真正开源啊,真的想鼓捣一下啊,拜拜Anders Hejlsberg大神。



Anders不知道写不写C#编译器啊,他是语言组参与语言设计,和编译器组做编译器开发好像不是一回事情……
12 楼 JeffreyZhao 2010-04-28  
@RednaxelaFX

多谢抓虫,栈和堆的确是我没写清,虽然我也知道这些

Java的Integer的例子的确非常可怕,我在slides里也写了。

int a = 1000, b = 1000;
bool b1 = (a == b); // true

Integer c = 1000, d = 1000;
bool b2 = (c == d); // false

Integer e = 100, f = 100;
bool b3 = (e == f); // true


这点真让人崩溃。

// R大以后去我的博客上抓虫吧……
11 楼 ZHH2009 2010-04-28  
八卦一下:

Neal Gafter是身在曹营心在汉呀,目前还是Javac Team的成员。

傻时C#编译器真正开源啊,真的想鼓捣一下啊,拜拜Anders Hejlsberg大神。


10 楼 JeffreyZhao 2010-04-28  
@night_stalker

多谢您的认真评论,我其实希望的也是您这样的回复,我也回复一下啊。

1、模式匹配是好东西,不过很多情况下更像是简化了一点点开发而已,我第一篇文章里说了似乎并非我看重的东西,或者说你能不能多提一点它对开发模式的影响?

2、能用break,next的确不错,不过each比ForEach好看100倍实在没理解

3、没看出对于开发模式有什么影响,我觉得C#和Java也都可以实现,也并非不可接受。
至于你说object.is_a?(Klass)和object is Klass,Klass.new和new Klass()孰优孰劣,我实在觉得实在不算什么。

4、1234_5678这种更加只是漂亮一点的写法而已了,我认为价值不高,要写那么个常量也是很少见的事情。任意长整型本来就是降低运行效率的东西,至于矩阵运算素数扩展就不是语言方面的问题了……

5、我实在不觉得字符串编码是什么问题,Python 3不也统一了字符串编码吗?

6、这……好吧。

7、挺好看的,但还是没有差距,不过这点的确比你举的其他一些,我觉得更好一些。

8、mixin是一种开发模式的改变,

9、不讨论库……

所以我觉得,其实你举的那么多例子,我都觉的不能说明Ruby - C#约等于C# - Java。我在第一篇文章里也说过了,我说C#比Java生产力高,并非是因为它好看或是省几行代码,而是可以引入新的优秀的好用开发模式和思维方式,这才是最重要的。你举的例子里,Minin是一例,其他的就没法让我满足了,呵呵。

附我的第一篇文章:http://blog.zhaojie.me/2010/04/why-java-sucks-and-csharp-rocks-1-thoughts-and-goals.html

相关推荐

    大师品软件_Why Software Sucks

    找到这也知道是书讲什么了,呵呵~~ 与该书Djvu格式相比改进了: 1、添加中文书签,书签翻译来源“csdn图书品读”提供的目录 2、导出pdf时压缩了图片,文件较小

    信息安全_数据安全_Why_the_role_of_CISO_sucks_and_w.pdf

    信息安全_数据安全_Why_the_role_of_CISO_sucks_and_w 信息安全研究 金融安全 安全人才 安全对抗 法律法规

    Why.Software.Sucks

    and got behind the concept of a book for the users of computers, not the programmers that they usually deal with. Instead of, "That's not what we do here," they stepped up and said, "Hey, cool, look...

    sucks-rocks:用于收集对小代码片段的反馈的 Web 应用程序

    很烂 用于收集对小代码片段的反馈的 Web 应用程序 后端 后端是使用以下库在 haskell 中实现的 REST-ish api: Scotty 用于 REST 接口声明 数据库访问的持久性(使用 sqlite 实现) 用于连载的 Aeson ...

    itsucks-0.4.1开源爬虫

    开源爬虫itsucks,最新版本,可以使用,简单的图形化界面,容易上手

    itsucks开源代码

    爬虫源码,开源 java 很好 强大 可扩展

    itsucks-0.4.1.zip

    itSucks是一个java web spider(web机器人,爬虫)开源项目。支持通过下载模板和正则表达式来定义下载规则。提供一个swing GUI操作界面。

    admiral-sucks:Chrome扩展程序旨在消除Admiral非常邪恶的Adblock Recovery:angry_face_with_horns:

    ,解压缩并将admiral-sucks文件夹拖至chrome://extensions Chrome扩展面板。 为什么? 是一家通过帮助网站将其内容货币化而获利的公司。 它们提供多种服务,但非常令人讨厌的是AdBlock Recovery :首先,它们向网站...

    itsucks:http

    ItSucks 网络爬虫 描述 这个项目是一个具有下载(和恢复)文件能力的java网络蜘蛛(网络爬虫)。 它还可以使用正则表达式和下载模板进行高度定制。 所有后端功能也可在单独的库中使用。 官网 执照 本地开发使用 将 ...

    your-band-sucks-v2:通过不良专辑封面分享音乐

    你的乐队吸v2 通过不良专辑封面共享音乐

    ak2新版内核AKAIO1.5

    + New Super Mario Brothers Minigames on AK2: If they don't work, set Download Play to "Disabled" and boot in non-DMA mode (hold down A while loading) + Misc bug fixes (Too many to list). AK-AIO 1.2 +...

    learnjava:学习AP CS-A考试

    AP的CS A考试其实比较简单,5分还是很容易拿到的,如果你已经有OOP基础只需要学习简单的java语法即可.这个repo的代码基本涵盖了AP考试会涉及的所有用法(对的就是这么点),其中[]?[]:[]三元运算符和Iterator并不会...

    why-your-test-suite-sucks

    这是关于测试的话题 在卡座中启动presentation.markdown以查看

    vld-2.5.1_2.zip

    ", or you think it stinks and would like to say "This thing sucks!", please feel free to [drop us a note][1]. Or, if you'd prefer, you can [contribute a small donation][2]. Both are very appreciated. ...

    weather-sucks:爱沙尼亚语心情天气应用程序

    利用脚本类型module 使用TypeScript编译器通过JSDoc键入check .js 我不建议将这种方法用于生产。 请直接使用TypeScript(如果需要输入安全性)。 即使在如此小的应用程序中,在JSDoc中维护类型也很麻烦。 URL中的...

    sucks:用python制作的小CRUD

    很烂 用python制作的小CRUD

    transcription-sucks:一个帮助转录稍微不那么糟糕的网站

    转录很烂 这是一个简单的项目,我试图让转录变得不那么糟糕。 不要在应用程序之间切换或使用特殊的外围设备,而是在网页上... 后退2秒: ctrl + j 向前跳 2 秒: ctrl + k 加速播放: ctrl + l 添加时间戳: enter

    Professional ScrumMaster's Handbook

    That sucks, and makes me sad—and spurs me to action. I don't want the original vision for ScrumMaster to become lost in the methodology/certifcation wagon train; I want people to reach their full ...

    IE Sucks-crx插件

    IE SUCKS这么糟糕,实际上是有趣的观看失败! IE样式信息条在页面中的障碍码时发光。 无广告! Internet Explorer是一个浏览器的F ****笑话,并字面上持有进步! 在逐步淘汰之前庆祝最终几天,用IE吸收插件。 每当...

    很烂:Ecovacs系列机器人吸尘器的简单命令行脚本

    目前已知可与来自北美和欧洲的Ecovacs Deebot N79,M80 Pro,M81,M88 Pro和R95 MKII一起使用。 它也适用于您的模型吗? 加入“ 的讨论。 如果您对协议感到好奇,那么我会提供。 我会很乐意接受请求。 为什么是...

Global site tag (gtag.js) - Google Analytics