Hello World
Spiga

Why Java Sucks and C# Rocks(3):Attribute与Annotation

2010-04-25 23:14 by 老赵, 11803 visits

上一篇文章里我谈了Java和C#语言中对于基础类型的不同态度,我认为C#把基础类型视做对象的做法比Java更有“万物皆对象”的理念,使用起来也更为方便。此外,C#拥有一个Java 1.4所不存在的特性,即Attribute(自定义特性),而在之后的Java 5.0中也增加了类似的功能,这便是Annotation(标注)。那么,Attribute的作用是什么,Java中的Annotation和C#中的Attribute又有什么区别呢,Java 5.0中又从C# 1.0中吸收了哪些优点?我们现在就来关注这方面的问题。

自定义特性与设计

Attribute是C# 1.0中的重要功能,它的作用便是为某个成员,例如类、方法或参数附加上一些元数据,而在程序中则可以通过反射操作获取到这些数据。例如,在.NET框架中,每个类型在默认情况下是无法被序列化的,除非我们为类型添加Serializable标记。如下:

[Serializable]
public class Product { ... }

Product类在标记了Serializable之后,就可以被BinarySerializer或DataContractSerializer等工具类序列化或反序列化。C#有个约定:所有的Attribute都(直接或间接)继承System.Attribute类,并且类名以Attribute结尾,但是在使用时可以省略。因此,事实上Serializable标记其实是SerializableAttribute类,它是System.Attribute的子类。

C#中的Attribute对于软件设计有非常重要的作用,例如Kent Beck评价到

NUnit 2.0 is an excellent example of idiomatic design. Most folks who port xUnit just transliterate the Smalltalk or Java version. That's what we did with NUnit at first, too. This new version is NUnit as it would have been done had it been done in C# to begin with.

简而言之,大部分xUnit框架都是简单地移植JUnit的代码,但是NUnit却利用了C#的Attribute提供了更优雅的设计,类似的观点在Martin Fowler所编的杂志中也有过更为具体的论述。因此,C#在这方面可谓大大领先于Java 1.4。幸运的是,在C#发布两年后Java语言也推出了5.0版本,增加了Annotation功能,这无疑缩小了与C#之间的差距。

只可惜,Java语言中的Annotation功能,我认为相对于C#语言的Attribute功能至少有两个缺点。

缺点1:失血模型

说起C#的Attribute与Java的Annotation,两者最大的区别便是:C#中的Attribute是类,而Java中的Annotation是接口。

由于C#的Attribute其实也是.NET中标准的“类”,因此与类有关的设计方式都可以运用其中,例如抽象类,抽象方法,重载方法,也可以实现接口等等。这类特性造就了一些非常常用的设计模式,例如可能对于大部分.NET程序员都非常熟悉的“验证标记”。

简单地说,这是一种通过标记来表示“验证逻辑”的做法,例如我们可以先定义一个基类:

public class ValidationResult { ... }

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public abstract class ValidationAttribute : Attribute
{
    public abstract ValidationResult Validate(object value);
}

ValidationAttribute类继承了System.Attribute,也就是说,它可以作为其他Attribute的基类。例如,我们可以定义这样一些通用的验证类:

public class RangeAttribute : ValidationAttribute
{
    public int Min { get; set; }

    public int Max { get; set; }

    public override ValidationResult Validate(object value) { ... }
}

public class RegexAttribute : ValidationAttribute
{
    public string Pattern { get; set; }

    public override ValidationResult Validate(object value) { ... }
}

于是,我们便可以在一个类的属性上进行标记,表示对某个属性的验证要求:

public class Person
{
    [Range(Min = 10, Max = 60)]
    public int Age { get; set; }

    [Range(Min = 30, Max = 50)]
    public int Size { get; set; }

    [Regex(Pattern = @"^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$")]
    public string Email { get; set; }
}

这样的标记便表示Age的合法范围是10到60,Size的合法范围是30到50,而Email需要满足特定的正则表达式。标记之后,我们便可以使用统一的代码进行验证,例如:

public static void Validate(object o)
{
    var type = o.GetType();
    foreach (var property in type.GetProperties())
    {
        var validateAttrs = 
            (ValidationAttribute[])property.GetCustomAttributes(
                typeof(ValidationAttribute), true);

        var propValue = property.GetValue(o, null);
        foreach (var attr in validateAttrs)
        {
            var result = attr.Validate(propValue);
            // do more things
        }
    }
}

如此,我们便可以轻易地获取每个属性上的验证条件,并调用Validate方法进行验证。我们有能力这么做的原因,是因为C#中的Attribute是类,这样我们可以使用抽象类ValidationAttribute进行统一控制。如果这段验证逻辑是由类库提供的,而开发人员想要增加额外的验证条件,也只需要自己定义新的类来继承ValidationAttribute,并提供自定义的Validate方法逻辑即可。这种方式大量出现在各类.NET的类库及框架中,给.NET程序员带来许多便利。

而在Java 5.0中,似乎Annotation和C#的Attribute在表现形式上差不多。例如,我们也可以定义一些“验证标记”:

public @interface RangeValidation {
    int min();
    int max();
}

public @interface RegexValidation {
    String pattern();
}

使用时似乎也差不多:

public class Person {
    @RangeValidation(min = 10, max = 60)
    public int age;

    @RegexValidation(pattern = "^\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3}$")
    public String email;
}

与C#不同,Java的Annotation其实是接口,它默认实现类库中定义的java.lang.annotation.Annotation接口,并且只能定义一些无参数的方法(不过可以指定默认值)——因为这些方法的作用其实只是类似于一些“字段”,只是用于保存数据,以便在程序中返回。这样看来,似乎和C#中没有区别,只是一个使用了“属性”,一个利用了“方法”而已,不是吗?

自然不是,区别很大。试想,现在如果您要编写一段代码来进行统一的验证,那么该怎么做?似乎没法做,因为在C#中我们可以通过统一的基类来获取所有表示验证的Attribute,然后调用定义在基类中的Validate方法。在Java语言中我们无法做到这点,因此如果要识别RangeValidation,那么我们就必须独立准备一段逻辑,而要识别RegexValidation则又是另一段不同的方法。因为两者的“识别”方式完全不同,因此我们无法使用相同的代码进行验证工作。

更关键的是,如果验证逻辑是由类库提供的,而开发人员想要补充额外的验证方式,那么该怎么做?我们可以提供自定义的Annotation,这很容易,那么识别这个Annotation的逻辑该如何交给类库呢?这个自然也有办法解决,但无论如何都会带来较多的代码量,且做不到C#般优雅,自然。

因此,Java的Annotation落后于C#的Attribute的关键之处,在于Java的Annotation只能定义为失血的对象,而C#的Attribute可以在需要的时候包含一定的逻辑,这样便可以让C#程序员获得更好的灵活性,使用更丰富的开发模式。与此相比,“类”和“接口”的区别,其实倒真只是表象罢了。

缺点2:古怪的约定

相比于上一个缺点来说,第二个缺点似乎并不那么严重,不过我认为这的确也是Java语言的Annotation设计中无法令人满意的地方。

在前面的代码中我们已经可以发现,其实C#的Attribute及Java的Annotation在使用上非常相似,为此我们再来仔细对比一下:

[Range(Min = 10, Max = 60)] // C#

@RangeValidation(min = 10, max = 60) // Java

这样看来,C#和Java在使用时的形式基本完全一致,都是使用名称+属性名的方式进行标记。不过其实C#和Java都有额外的语法,例如在C#中,我们可以这样定义RangeAttribute类:

public class RangeAttribute : ValidationAttribute
{
    public RangeAttribute() { }

    public RangeAttribute(int min, int max)
    {
        this.Min = min;
        this.Max = max;
    }

    public int Min { get; set; }

    public int Max { get; set; }

    ...
}

与之前的RangeAttribute相比,新的定义增加了两个构造函数定义,一个是无参数的构造函数(其实原来的定义也有,只不过由编译器自动添加),还有一个构造函数则直接接收min和max参数,这样我们便可以直接通过构造函数来标记Attribute了:

[Range(10, 60)]

当然,有人说这种做法不如显式指定Min和Max来的清晰——可能是这样吧,但是在很多时候通过构造函数传参也有优势,例如我们可以重新定义之前的RegexAttribute为:

public class RegexAttribute : ValidationAttribute
{
    public RegexAttribute(string pattern)
    {
        this.Pattern = pattern;
    }

    public string Pattern { get; private set; }

    ...
}

在这里我们为RegexAttribute提供了一个接收pattern的构造函数,并将Pattern属性的set方法设为private。于是我们便可以这样使用RegexAttribute了:

[Regex(@"^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$")]

这么做有两个好处:首先,外部无法设置Pattern属性的值,这点加强了对象的封装性。其次,这里相当于强制RegexAttribute在使用时必须提供一个pattern参数(虽然无法进行验证)。这样,代码在使用时既显得优雅,可读性也非常良好。但其实,我认为更关键的是,这种使用模式和创建一个对象,并为其属性进行赋值一样:我们可以选择任意的构造函数创建对象,再“有选择地”进行属性赋值。例如上文AttributeUsage的使用:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]

这里的含义是,创建一个AttributeUsageAttribute类,提供AttributeTargets.Property作为构造函数的参数,并同时将AllowMultiple属性设为true。可见,这种做法给了我们相当自由性——而且非常自然,没有奇怪约定。在设计一个Attribute的时候,我们一般可以提供几个常用的构造函数,在大部分情况下使用这些构造函数也已经足够了。除此之外,Attribute对象的属性包含了默认值,在必要的时候可以进行修改。

在Java语言中,事实上我们也可以修改RegexValidation类,让开发人员可以通过这种方式来使用:

@RegexValidation("^\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3}$")

只要我们可以把RegexValidation改成这样即可:

public @interface RegexValidation {
    String value();
}

在Java语言中,假如Attribute的一个成员名为value,且没有其他成员(或是其他成员都提供了默认值),那么便可以如C#中构造函数般使用。那么……

  • 如果我想使用“构造函数”的方式传递数据,但成员名还是想用pattern,可以吗?
  • 如果我想使用“构造函数”的方式传递多个参数,可以吗?

不可以。我也不知道为什么会有这种特别的约定规则呢?可能和Annotation是接口有关吧。接口没有构造函数,因此没有一个合适的方式以省去成员名的方式传递参数,只能指定一个特别的名称了——但对于开发人员来说,凭什么我的Regex值一定要叫value而不能叫pattern呢?

Java 5.0学习C#

我不知道为什么有了C#的优秀榜样,Java 5.0却还是不愿意做的更好。其实C#中的Attribute也有缺点,例如无法使用泛型,所以Java完全有胜过C#的机会。其实在以后的文章中您也可以发现这样一个现象:C#的榜样并不完美,但Java的进化更为糟糕。对此,我们除了一声长叹又能怎么办呢?

除了Annotation之外,Java 5.0还从C#处学习了以下功能:

  • 可以使用enum关键字定义强类型的常量——C# 1.0中也有类似功能(好吧,我承认,其实Java的enum功能比C#中要丰富一些)。
  • 可变参数,即可以使用“一一列举”形式,提供某个方法最后一个数组参数的内容——其实就是C# 1.0中的params。
  • 增强了for的能力,可以方便地使用枚举器(Iterator)——这其实就是C# 1.0中的foreach。

那么,到底是谁是所谓的“copy cat”呢?就像我在第一篇文章中写的那样,“自从C# 1.0诞生之日起,就只出现Java借鉴C#特性的情况,至今已将近10年”,以后我们还可以看到更多例子。我并不想说所谓的“抄袭”,我只想说“学习”或是“借鉴”。我认为,只要是优点,出现雷同这都是完全正常且值得鼓励的。我现在提到这些,主要的目的是想告诉那些固执地认为“C#只是Java的山寨复制品”的同学们一个事实。

相关文章

Creative Commons License

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

Add your comment

120 条回复

  1. 无恙
    58.19.27.*
    链接

    无恙 2010-04-25 23:45:30

    好像今天可以占个好位置!!

  2. YeanJay
    58.100.73.*
    链接

    YeanJay 2010-04-25 23:50:07

    抢个沙发!!

  3. jason
    124.160.93.*
    链接

    jason 2010-04-26 00:03:36

    呵呵,谢谢老赵的辛苦,让我可以知道java和c#原来有这么多相同和不同的地方

  4. evanmeng
    222.70.181.*
    链接

    evanmeng 2010-04-26 00:05:59

    老赵能不能再比一比Python里的decorator和这两者的差别?

  5. 老赵
    admin
    链接

    老赵 2010-04-26 00:08:59

    @evanmeng

    根本不是一类东西,没法比。

  6. mjo
    210.73.14.*
    链接

    mjo 2010-04-26 00:16:53

    我比较喜欢这篇,就应该和Java 1.5比。Java的进化受那个标准委员会的约束太多了,说其保守都是好话,简直是帮倒忙,想想EJB的进化,如果没有spring不知道现在的EJB会演化成什么样子。但是,spring可以在应用框架级影响Java应用标准,却不太可能在语言级影响。

  7. 老赵
    admin
    链接

    老赵 2010-04-26 00:26:05

    @mjo

    我是按照时间顺序一步步来的,最终会比到Java 7和C# 4,这样可以看出双方演变过程中产生的巨大差距。

  8. 链接

    Ivony 2010-04-26 00:35:56

    怎么说,其实.NET的Attribute的确是一个非常棒的东西,当然,作为类型而言,它的确提高了许多复杂度。如果就修饰元数据这个功能来说,Java的Annotation的能力是已经足够了。或者说在这个问题上,并不能说是Java太烂,而是C#太好吧。当然这种足够好也带来了一些副作用,例如性能问题。记得老赵已经遇到过了吧。如果这个Attribute不能这样随心所欲,那么在获取实例的时候,也就不必调用构造函数等等步骤,可以最大限度的得到最好的性能了吧。

  9. 老赵
    admin
    链接

    老赵 2010-04-26 00:48:18

    @Ivony

    用了.NET的Attribute,我觉得Java的Annotation不够啊,就像我举的例子。当然Java也可以实现类似的功能,但是的确需要额外的代码和类的支持了,不如C#那么自然……

    说到性能,我倒真不担心Attribute的性能,以前我们不也讨论过嘛,完全可以写一套API来代替BCL的相关方法,性能提高很明显,就像直接创建对象设置属性那样。

  10. 链接

    coderzh 2010-04-26 01:06:03

    @evanmeng

    Python里的decorator可以改变函数或类的行为,可以想象为设计模式的Decorator Pattern.

    .NET的Attribute和Java的Annotation的作用就像老赵说的:“它的作用便是为某个成员,例如类、方法或参数附加上一些元数据,而在程序中则可以通过反射操作获取到这些数据”

  11. alex
    117.136.0.*
    链接

    alex 2010-04-26 07:05:36

    annotation用接口倒不是大问题,毕竟java一直的思想就是宁可罗索也要清晰简单,这和c#在设计初衷上就有区别,实际上这也是java被广泛接受的重要的原因。的在目标不同的情况下,某些语言特性的比较似乎不太公允。您能否就“罗索但能让更多的人易懂”和“更丰富的语言特性让更聪明的人表达更自由”间做一个比较?呵呵

  12. Kong
    113.109.116.*
    链接

    Kong 2010-04-26 08:54:48

    唔。。。 标题里有两个词不认识:Sucks和Rocks 我是看了内容才知道标题的意思的。。。

    是因为中文不好表达所以才用英文的吗?

  13. 看看
    218.107.246.*
    链接

    看看 2010-04-26 08:55:05

    老想起一个问题.今天问下.就是为什么MS不在IEnumerable上实现扩展方法ForEach,而只有List上有,不知是出于什么目的考虑,是延迟加载吗?

  14. avlee
    119.62.12.*
    链接

    avlee 2010-04-26 08:58:45

    本来就是相互学习的过程,同样都受到其他语言的竞争。

  15. doylecnn
    222.68.249.*
    链接

    doylecnn 2010-04-26 08:58:55

    罗索和清晰简单 怎么看都是对立的...

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

    1-2-3 2010-04-26 09:01:39

    不知道是不是我孤陋寡闻——怎么貌似没看到Java那边厢有像样的反击呢?老赵说Java(语言)没C#好也有几年了吧,这根本就不像论战嘛,没法围观了。

  17. 老魏
    123.115.135.*
    链接

    老魏 2010-04-26 09:19:28

    语言只是一个工具,与其说他的好与坏,不如将它发挥到你所能的极致。

  18. 链接

    情缘 2010-04-26 09:25:55

    确实如老赵所说的一样,java中的注解太难用了,我只能这么说。现在java中的Hibernate,Spring 等高版本都使用了注解Annotation 代替了xml文件的配置,号称零配置,但是感觉使用了这样的替代之后,感觉很多东西都变得呆板,或许因为语言的特点,他就决定了使用Annotation替代xml文件的配置就不是那么的灵活。

    现在.NET中的Linq to SQL,Linq to Entity 都是使用的Attribute,包括WCF中的契约的修饰都是使用的Attribute,这种面向对象的修饰方式方便了许多。

    不过有一点,java中的Annotation,C# 中的Attribute都有一个共同的特点,那就是直接编译到类文件的字节码文件中去了,这导致.NET 中的Linq,java 中的Hibernate 高级版本的使用,每次修改都需要一次编译,他们都不如使用xml文件灵活。

  19. 老赵
    admin
    链接

    老赵 2010-04-26 09:33:28

    @情缘

    呵呵,我觉得应该用Attribute/Annotation,因为其实没有什么场景是不需要编译,只要换一下XML就够的啊,不是吗?映射方式改变是大事,基本上其他代码也要跟着改的。

  20. 老赵
    admin
    链接

    老赵 2010-04-26 09:35:37

    @看看: 老想起一个问题.今天问下.就是为什么MS不在IEnumerable上实现ForEach,而只有List上有,不知是出于什么目的考虑,是延迟加载吗?

    上次一个MS大牛,名字忘了,说ForEach理论上会带来一些麻烦,如产生闭包等等,且不够函数式。但是我其实一直没有接受,要我的话我会在BCL里加上ForEach的。现在就自己扩展吧,还好也就几行代码。

  21. 老赵
    admin
    链接

    老赵 2010-04-26 09:36:56

    @老魏: 语言只是一个工具,与其说他的好与坏,不如将它发挥到你所能的极致。

    钝刀再强也发挥不出宝刀的威力啊,不知道工具的好坏,发挥到极致可能也不过尔尔……

  22. 老赵
    admin
    链接

    老赵 2010-04-26 09:41:15

    @1-2-3: 不知道是不是我孤陋寡闻——怎么貌似没看到Java那边厢有像样的反击呢?老赵说Java(语言)没C#好也有几年了吧,这根本就不像论战嘛,没法围观了。

    .NET阵营会说,那是因为Java阵营自知理亏不敢露头了。

    Java阵营会说,那是因为Java阵营不屑于此类比较。

    我说,欢迎讨论,只要理由靠谱就行……

  23. 老赵
    admin
    链接

    老赵 2010-04-26 09:46:06

    @avlee: 本来就是相互学习的过程,同样都受到其他语言的竞争。

    所以演变很重要,其实Java平台上的其他语言,如Scala,Groovy都在演变,我认为这个才是正确的做法。在我看来Java语言最大的问题还是抱残守缺……

  24. fuxy
    112.66.71.*
    链接

    fuxy 2010-04-26 09:48:10

    我来补充几点:

    1,两者的应用范围不太一样,C#可以对程序集或者模块应用attribute,java的annotation不能用在JAR文件上,C#不能对命名空间应用attribute,Java可以对包应用annotation。

    2,java中有@Target({ElementType.ATTRIBUTE}),C#不能定义出只能作用于attribute类型上的attribute。

    3,Java的annotation则可以选择作用范围是CLASS、RUNTIME或者SOURCE, 所以不一定会带到运行时,甚至不一定会编译到.class文件里。而C#的attribute总是能带到运行时的。

  25. 链接

    情缘 2010-04-26 09:49:34

    @老赵: 呵呵,我觉得应该用Attribute/Annotation,因为其实没有什么场景是不需要编译,只要换一下XML就够的啊,不是吗?映射方式改变是大事,基本上其他代码也要跟着改的。

    我同意你的见解,的确编译是必学的,我的意思就是说,Annotation,Attribute 和xml文件配置比较起来,xml文件的灵活性更大一些,因为它本身就是文本格式,只需修改保存即可。

  26. pingf
    121.34.59.*
    链接

    pingf 2010-04-26 09:56:16

    姐夫你好, 按照你这个说法,c# 1.0 产生的时候难道没有借鉴JAVA么?

  27. 链接

    clk_z 2010-04-26 10:04:30

    @pingf: 姐夫你好, 按照你这个说法,c# 1.0 产生的时候难道没有借鉴JAVA么?

    大哥?大叔?大爷?您能不能把文章看完再评论?

    我都替老赵感到杯具!呵呵!

  28. abc
    58.214.118.*
    链接

    abc 2010-04-26 10:18:43

    请教一下Attribute和多态类型有没有什么关系?

  29. abc
    58.214.118.*
    链接

    abc 2010-04-26 10:24:20

    好像是一种类型的两种写法。是吧?

  30. WindEagle
    61.172.241.*
    链接

    WindEagle 2010-04-26 10:40:44

    的确,C#中的Attribute也有缺点,例如无法使用泛型,我一直没搞清楚为什么MS不解决这个问题,老赵可以指点吗?

    另外,说到泛型,.NET的泛型为什么不能像C++的模板一样特化呢?为什么不像C++的Trait,一样搞出“瘦泛型”呢?这又是什么原因?

  31. 老赵
    admin
    链接

    老赵 2010-04-26 10:41:58

    @abc

    没看出Attribute和多态类型的关系……还有多态类型是指什么?

  32. 老赵
    admin
    链接

    老赵 2010-04-26 10:43:25

    @WindEagle

    不好意思我不知道啊,哪位有想法不妨讨论一下?

  33. 老赵
    admin
    链接

    老赵 2010-04-26 10:46:09

    @pingf: 姐夫你好, 按照你这个说法,c# 1.0产生的时候难道没有借鉴JAVA么?

    按照我这个说法?按照我哪个说法?我可没这么说过。C#的优秀之处就是它能吸取其他语言的优点来增强自己。这并不容易,因为并非把各美女最漂亮的五官拿来组合在一起就是最美的。所以要又选择,要借鉴理念,并以自己的方式表现出来。

  34. abc
    58.214.118.*
    链接

    abc 2010-04-26 10:50:23

    多态类型就指泛型

  35. suiye007
    222.51.26.*
    链接

    suiye007 2010-04-26 11:08:38

    我个人还是同意老魏的说法:语言只是一个工具,与其说他的好与坏,不如将它发挥到你所能的极致。

    无论哪种语言,哪种工具,无不是在进步的,只是有些进度慢了一点,像发达国家与发展中的国家一样!有些是思维的问题,像人与人之间一样,处理问题的思路不一样。

  36. michael
    218.24.4.*
    链接

    michael 2010-04-26 12:58:53

    我一直有个疑问,为什么java生产力低下?老赵一直强调比较的是语言,但是一个语言的生产力低下,好像不是单纯语言比较吧?

  37. 老赵
    admin
    链接

    老赵 2010-04-26 13:09:25

    @michael

    我一直有个疑问,为什么java生产力低下?

    你说的没错,我也从来没有说Java平台生产力低下,我目前说的只是Java语言生产力底下。

    老赵一直强调比较的是语言,但是一个语言的生产力低下,好像不是单纯语言比较吧。

    想要说明语言的生产力底下,除了单纯比较语言还能比较什么呢?语言和平台是应该区别对待的,我以前写过关于语言和平台的文章,给您参考一下。

  38. abc
    58.214.118.*
    链接

    abc 2010-04-26 13:59:59

    语言么,从信息的角度看就是我们构成消息时进行选择的自由度。C#和java首先一个弊端就是和平台捆绑在一起。这就丧失了最大的自由,即选择权。

    C#固然好,java也不错。但是也可以说非常不好,这就是好的不好的方面。

    还有一个和平台捆绑本身有关的问题,即是用这种语言基本就是使用它的库,用户的自由度很小。这方面又进一步丧失自由。当然也可以说生产率很高。这就是高的低。

  39. abc
    58.214.118.*
    链接

    abc 2010-04-26 14:44:09

    支持对java和C#的语言特性进行充分辩论。 期待老赵后文!

  40. 链接

    yang 2010-04-26 15:01:11

    php应该是因为linux和mysql的流行,所以达到asp.net所望尘莫及的程度。现在很多server月租只有10$上下,按10个账户算,收回winser+mssql的成本基本就是浮云。 属性更像是C编译宏的感觉,与其说是语言特性,不如说是IDE的机能。 比如C环境下的Qt,他的很多宏都是用来生成自动代码,来达到提高生产力的目的,而这些本身是并不被C支持的。 C#里的属性应用,比如NUnit,比如序列化,比如OR,这些都在很大程度有着自动生产代码的意味吧,java的标注也应该类似。

  41. 链接

    Ray 2010-04-26 16:10:57

    @mcpssx

    其实php现在只有一种数据结构,就是array. linq这个东西,写起来可能也有用,但是没有也没什么。

    php我不懂。但是C#里面的Linq那一系列的东西我是熟悉的,至少对于C#来说,远非语法糖这么简单。有和没有本质上是what to do与how to do的区别。

    让开发人员将注意力集中于what to do而不是how to do恰恰就是提高生产力的关键因素之一。不仅能生产力的提高,还能保障代码的质量。

    目前我也是没法离开linq了。

  42. 老菜
    60.215.45.*
    链接

    老菜 2010-04-26 16:54:34

    正在等这篇文章呢,看看。

  43. jaren
    221.217.38.*
    链接

    jaren 2010-04-26 17:47:34

    mcpssx说的也有一定的道理,当然我更偏向于老赵的看法,现在因为微软的一些举措,所以大家会有不太一致的看法,比如:对于桌面市场对于winform基本上不太提倡了,全力转向了WPF和SL,还有Asp.net的webform相对于Asp的巨大转变以及对Asp的事实上的抛弃,造成了PHP对于这块internet应用的大量钟情于快速方便的脚本语言开发者的吸引,一部分甚至选择了jsp而后逐渐转向java社区.我想微软也意识到了这样的问题,但是恢复ASP是不太现实了,所以有了ASP.NET MVC等等技术向Internet应用发力,对于PHP也是异常欢迎,不希望成为对手,更希望作为补充,而当然对于内网应用,webform仍然有很大的吸引力,winform也同样可以满足相当多的需求,虽然总体趋势是以XAML为主了,以至于WindowsPhone7亦支持SL.

    不过我们似乎有点跑题,老赵的文章说的很清楚是针对于仅仅语言层面上Java和C#的比较,所以还是不要牵扯其他的语言和技术,否则讨论起来没完了.我对于C#的一个比较喜欢的地方是自1.0就有的Delegate,这个Java没有,由于Delegate这种函数回调机制,我们可以把事件驱动很轻松的引入面向对象编程模型,使面向对象在函数级上可以有很多灵活的设计,也可以做出很多方便的重用,比如datareader的读取逻辑可以很方便的从基本连接数据库和关闭连接释放资源等等操作抽离出来,另外像事务处理也可以类似简化,虽然Java在事件驱动和其他领域也可以透过设计模式和框架等等方法同样实现,可以我觉得C#对于C++的很大的继承,有助于强大功能的实现,可以很好地补充面向对象范式的某些不足.好像看过一个对话,说Anders是回调函数控,而高司令是interface控.:)当然对于delegate也可以算是平台支持的不同吧.

    现在大家都有共识了,语言的特性并不是越多越好,看看恐怖的C++就知道了.另外比如: C# 3.0 引入了一个构造对象初始化的语法,目的意在可以简化重复的构造函数重载,那么假设使用中有一些必须初始化的变量,好像文中attribute的初始化例子一样,又如何利用这个先进的语法呢?恐怕还要老老实实的用老方法,那么这势必增加了编程者的注意力,不了解不熟悉这个语法的人很可能写出不符合规范的代码,这也增加了大家学习的曲线.还有使用了自动属性,你就不能对于内部变量手动控制了, 有的时候还要用回老方法,这都牵扯精力.我觉得由于有这么多强大的语法,对于C#最佳实践的讨论也是很有必要的.

    水平有限,说得不好,还是期待老赵的下一篇.

  44. Ivony
    124.193.150.*
    链接

    Ivony 2010-04-26 18:59:12

    @mcpssx

    怎么说,我理解你的心情。但就语言和这个系列的文章来说,Java语言比C#语言更糟糕是不争的事实。的确现在VB.NET也很强大,但和C#比起来,也只能说是各有千秋,我很眼馋VB.NET的XML Literal和lambda表达式可以直接调用以及索引属性这些特性。但C#也有着自己的特色,例如指针,例如更严谨、简练和类C风格的语法。

    好,我们现在把Java语言和C#语言放在一起比较,胜负立分不是么?

    语言本身的优劣并不是我们选择的唯一因素,我同意。但单就语言而言,我们只比较语言的话,那么结论岂不是很明显。一个语言很Sucks不代表我们就要迅速而果断的抛弃它,但至少说明我们应该做点什么。毕竟现在已经不是十年前,时代在变化,如果熟悉.NET和VS平台的话,会发现其实C#程序员也不是天天在用C#么,XSD用于描述数据架构,XAML用于描述用户界面。。。。。选用合适的语言做合适的事情,这,难道不是很棒的技术?

    当然,这是很棒的技术。作为技术人,我们应该更多的专注于技术本身,什么技术是先进的,什么技术是过时的。作为一个Developer,其实并不需要任何大牛来告诉我们,自己心中就有一个评价才对。

    我也做过PHP的开发,所以很清楚PHP的优势和缺陷在什么地方。事实上对于社区这类型的网站而言,体系严谨的ASP.NET是比PHP或ASP更为适合的。至于ASP的开发人员为什么不转到ASP.NET,我觉得这个问题很无聊,因为JavaScript的开发人员也没转到Java么。这是不同的技术,除了名字相似之外没有太多共同点。

    ASP的开发人员并非是不愿转移到ASP.NET,而是这个时代已经过去了,脚本语言的时代已经被历史的浪潮狠狠的摔在沙滩上。PHP不也在不断发展和磨去自己的脚本痕迹么?

  45. 不信算了
    221.223.88.*
    链接

    不信算了 2010-04-26 20:00:53

    记得在上一讲中有个人回复说:

    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.

    其实呢,也确实如此。

    再有老赵以前说过“先做人再做程序员”。

    所以在我看来老赵比较看重的是“Java的不思进取”,继而提出一个人的看法。这也反映了一个人的精神面貌。诚然一个人无法做的尽善尽美,可是有大部分人指出你存在问题了,你因该去反思,然后去改进。

    再者,记得mcpssx也说:“Java稳定”,没有.NET这样今天Linq明天或许entity framework。不过呢,核心的地方也就那点。后面的都是微软为了提高生产力做的改变。之前我也问过老赵该学什么?“学习语言的基础”,我觉得有道理抱歉我是新手。

    在回复中呢讨论却有点变味了,都固有自己的思想:比如比较是open(XX)还是XX.open(),记得面向对象应该是更容易接近人的思维,人与人不一样这点就不要比较了。死了(你)和你.死了,都有自己的说法。

    社会主义说资本主义不好,可是呢中国却走特色的社会主义(资本主义)。C#比Java高级,不过呢大家也没有否认Java带来的贡献。

    菜鸟纯顶老赵而来。

  46. 链接

    franzcai80 2010-04-26 22:36:33

    c#代码看起来更优美。老赵是追求代码之美的人。你跟他说Java也能实现没有说服力啊。这个系列对深入学习Java也很有帮助。

  47. Duron800
    113.44.0.*
    链接

    Duron800 2010-04-26 23:21:38

    linq跟sql思想接近,但是有了sql,有人还非要把它orm转变成对象来处理了,现在还要NoSQL呢。所以其实不论使用哪种方式,linq的还是过程式的都不是什么大问题。而且说不定你linq用了几天,微软又要你用entity framework去了。

    这不是典型的不知道LINQ到底是干什么的嘛。你以为老赵说的是LINQ TO SQL 或者 ORM ?

  48. hippo
    121.34.47.*
    链接

    hippo 2010-04-27 23:11:01

    我本想模仿老赵写一篇“Why 普通话 Sucks and 客家话 Rocks”,然后再加一系列“(一)、(二)、(三)”不过后来想想还是算了,费时间耳。 为什么呢?

    你认为是缺点的东西,在另外一个人看来,恰好是其优点。比如尽管很多人都认为骨感的女孩比较漂亮,不过貌似我周围的朋友当中不少是喜欢脸圆身圆肉感的女孩。

    窃认为楼主的(一)~(三)并没有扣题:“Why Java Sucks and C# Rocks”,比较贴切的应该是“What's the differences of Java and C#”

    期待更扣题的下一篇

  49. hippo
    121.34.47.*
    链接

    hippo 2010-04-27 23:30:23

    @老赵

    @mcpssx: 问题是1.0刚出来的时候,c#应该没有lambda, 而vb当时已经有了动态绑定,com调用,默认参数和命名参数,那为什么当时还要选择c#呢?

    真有吗?那我就不知道了,没人让我用VB吧,如果有人像我一样写个Why C# Sucks and VB Rocks说不定我就改变了,呵呵。我觉得你举这种假设很没意义,基于现状来谈不就好了么。以前应该改变的地方没有改变,那可能是个问题,但这不代表现在遇到问题也应该不改变。

    这点我可以证明,VB从3.0开始(1993年生产的)已经有后期动态绑定、默认参数和命名参数,甚至可以不需要声明变量,现在回头看是不是觉得VB很酷?C# 4.0在翻炒十几年前的东西了

  50. 老赵
    admin
    链接

    老赵 2010-04-27 23:30:41

    @hippo

    我觉得已经不仅仅是“差别”,而是明显“差距”了啊。就好比说聪明人和笨蛋,我说聪明人好,您非要说也有人喜欢笨蛋,虽然这“理论上”没错,但也就没意思了啊,这时候说“有人……有人……”在我看来就已经纯粹是套话了……也罢也罢,我会继续写的,不知道您的观点究竟可以坚持到第几篇,嘿嘿。

  51. 老赵
    admin
    链接

    老赵 2010-04-27 23:35:52

    @hippo: 这点我可以证明,VB从3.0开始(1993年生产的)已经有后期动态绑定、默认参数和命名参数,甚至可以不需要声明变量,现在回头看是不是觉得VB很酷?C# 4.0在翻炒十几年前的东西了。

    不要轻易下结论啊,C# 4这可不那么简单,看看《二十行C#代码打造Ruby Markup Builder》吧,即便表面有些类似,具体做成什么样子在能力上还是有很大差距的。

  52. GuangXiN
    123.120.35.*
    链接

    GuangXiN 2010-04-28 00:55:13

    PHP语言本身确实没什么搞头,它基本没法独立承担软件的任何重要模块。几乎所有大问题的解决方案全得依靠服务器基础构架:换用更轻量级的lighttpd或者ngix,MySQL服务器配置成Master-Slave或者Cluster,加入memcached或者TokyoTyrant分布式缓存,对静态内容作CDN等等。一个PHP程序员直接用PHP做得最多的是字符串处理和关联数组处理。PHP大多数库都是对成熟的C++解决方案的包装(gd、curl、mcrypt、iconv等等),或者就是某些客户端库(mysql、memcache、gearman之类)。.Net或者Java程序员遇到平台没有提供解决方案的问题时可能可以考虑自己编写一个库去解决,而PHP程序员遇到问题时往往只能寻找C/S构架的解决方案或者将C++库引入为PHP模块,几乎不可能用PHP实现一个优秀高效的PHP库。

  53. gabry
    210.13.69.*
    链接

    gabry 2010-04-28 07:25:07

    怎么感觉像是清政府在上朝的时候嘲笑洋人???

    对着满朝文武喊,洋人,老子说的对不对?不服站出来说话

    没来的请举手,没人举手,人都来了

  54. 链接

    陈梓瀚(vczh) 2010-04-28 07:50:40

    从一个编译器的开发者的角度来说,老赵说的东西大部分都是正确的。其实比较一门语言抛弃库来讲在天朝的现实意义不大,正如袁腾飞同学说的,“天朝只关心能够立刻变成钱的东西。”那么比较一门语言的时候鉴定抛弃库是什么人呢,就是做学术的人。当然任何一个做学术的人并不代表他不做工程,这是不矛盾的。其实搞搞基础研究也是挺有意思的,这就是为什么我明知我的codeplex工程赚不了钱也发不出论文还没是继续写的原因。

    纵观上面的讨论,大部分还是文质彬彬地没有理由地漫骂。我跟老赵一样也在讲没有理由地反对是没有意义的,不过人家就是喜欢这样。为什么呢,如果你否定了java,并且将影响扩大开去,那么那部分人的饭碗就要完蛋了。虽然我认为他们是活该,离不开java跟离不开微软的IDE和C#其实没任何区别。

    总的来说我还是很支持老赵的,说什么话至少都是拿出了理由的。

  55. 看看
    218.107.246.*
    链接

    看看 2010-04-28 09:27:34

    感觉怎么说了,虽然@mcpssx口头说知道Linq不是Linq to Sql,可惜他就是就个意思。Linq用起来是一个思想概念的转变,因C#的Linq我学了下函数式编程语言F#,感觉更深。

  56. 老赵
    admin
    链接

    老赵 2010-04-28 09:39:38

    @看看

    事实上在Stack Overflow上有许多人和你的看法相同,就是说学习F#对LINQ的理解更深刻。前一段时间逛Stack Overflow上F#话题有感,的确很有印象。

  57. 链接

    Kurax Kuang 2010-04-28 09:40:37

    @mcpssx

    您就不要辩论了……我几篇看下来,您根本对.NET平台就是一知半解嘛

    LINQ跟SQL有个毛关系啊,就因为你看到都有SELECT FROM嘛?

  58. 看看
    218.107.246.*
    链接

    看看 2010-04-28 10:09:18

    @mcpssx: 既然没有毛关系,就更不是必须的了。没有linq,并没有看出来.net程序员比java和php程序言生产力高。

    你应该认为Linq to Sql能提高生产力,不过这点好像不对,Java和PHP我想应该也有ORM框架的吧,不会因为一个Linq to Sql比Java和Php有生产力..........

  59. 老赵
    admin
    链接

    老赵 2010-04-28 10:23:15

    @mcpssx

    我自然知道“生态环境”的重要性,所以我推荐Java程序员去用Scala,而不是C#。算了我不多说了,我想等我继续写下去你就会知道的,呵呵。

  60. 链接

    Kurax Kuang 2010-04-28 11:16:15

    我的观点是,C# 1.0确实不咋地,没有什么亮点,但C#在进步,而且进步的很快。泛型是C#的一大进步,自此之后,这门语言就开始变得越来越“上等”。

    我并不在乎是用的语法糖还是用的高级技术,对于我来说,能让我快速合理地设计以及开发出面向商业的应用程序,就是最大的价值。在比较过多门语言和其对应的类库后,我选择了C#,并且为此坚持了近10年,C#和.NET并没有让我失望。

  61. 看看
    218.107.246.*
    链接

    看看 2010-04-28 13:10:38

    @mcpssx

    呵呵,你一个人和我们这么多人口水,也难为你了。微软似乎宣布不再支持linq to sql了.对我来说没有任何影响......对于用linq的人来说也会感觉不到影响.....

  62. abc
    58.214.114.*
    链接

    abc 2010-04-28 13:19:52

    如果能比较一下各自的基础设施和编译器比较有意思

  63. hippo
    113.88.41.*
    链接

    hippo 2010-04-28 14:35:58

    呵呵,我又回来围观了,多得 @mcpssx 的热烈讨论,否则老赵花这么多时间写这么多文字就白费了,也许热烈的争辩才是老赵所需要的效果。

    来看看我的语言旅途吧:

    • 学习阶段:GWBasic 5 -> TC2.0 -> BC++ 3.0 -> Delphi(Object pascal)
    • 工作阶段:Delphi-> VisualBasic 5.0 -> VB6(DCOM) -> Java -> c#.net(network server,IOCP)

    我每用一门就爱一门,之所以转语言完全是工作需要,同时也没有贪新厌旧,时不时还拿出 vb6和delphi 操刀帮朋友解解难题。老赵你望尘莫及了吧,哈哈哈

  64. hippo
    113.88.41.*
    链接

    hippo 2010-04-28 14:44:43

    @陈梓瀚(vczh):……没有理由地反对是没有意义的,不过人家就是喜欢这样。为什么呢,如果你否定了java,并且将影响扩大开去,那么那部分人的饭碗就要完蛋了。虽然我认为他们是活该,离不开java跟离不开微软的IDE和C#其实没任何区别。

    你这句话放在十年前可能还能成立,现在我倒没有听说哪个人离开哪门语言就丢饭碗的,大部分人从一门语言转到另外一门语言所需的成本是很低的,更别提Java<->C#了,仅仅从语言层面来转的话,普通程序员大概1周时间就适应了。

    我的观点是,在目前主流的十来个语言当中选什么样的语言只跟个人癖好和工作需要有关,不见得哪门语言会在几年之内就彻底被淘汰,至于哪门语言更多人用,也是完全由市场决定,至于市场由什么决定,这个跟语言所处的环境(平台、社区)有很大关系

  65. 链接

    陈梓瀚(vczh) 2010-04-28 14:54:29

    hippo先生,比较个开发效率什么的不看库就算了,换语言来工作那可是万万不能忽略库的啊。个人觉得语法什么的一天就能换过来了,库可不一定。一个java高手自然是一个编程高手,但无论怎么【一周】,都不可能在之前没接触过.net的情况下【把.net用得跟java一样好】。

  66. hippo
    113.88.41.*
    链接

    hippo 2010-04-28 18:33:56

    @陈梓瀚(vczh): hippo 先生,比较个开发效率什么的不看库就算了,换语言来工作那可是万万不能忽略库的啊。个人觉得语法什么的一天就能换过来了,库可不一定。一个java高手自然是一个编程高手,但无论怎么【一周】,都不可能在之前没接触过.net的情况下【把.net用得跟java一样好】。

    你的话我完全同意,而且我甚至认为一个语言的周边环境(包括运行平台、库、资料、经济成本)甚至比语言本身更重要,我在博主的第一篇文章就这么回复了,不过博主反复强调他的文章只比较“语言本身”,所以我就单单谈“语言本身”咯

  67. zsbfree
    218.241.140.*
    链接

    zsbfree 2010-04-29 08:45:51

    @mcpssx

    你到底懂不懂.net.linq,真是悲剧。对不懂的事情不要乱开口。开口的拿出依据,感觉你就是在无理取闹。

  68. mcpssx
    59.175.192.*
    链接

    mcpssx 2010-04-29 10:13:56

    @zsbfree

    .net,linq又不是什么火箭科技。

    最大的悲剧的恐怕就是那天微软宣布不再支持linq了,又隆重推出一个新框架了。

  69. zsbfree
    218.241.140.*
    链接

    zsbfree 2010-04-29 10:15:34

    @mcpssx: .net,linq又不是什么火箭科技。最大的悲剧的恐怕就是那天微软宣布不再支持linq了,又隆重推出一个新框架了。

    搞了半天,原来是这个啊。呵呵。和着在你心里在纠缠这个。

    你赢了。

  70. zsbfree
    125.39.108.*
    链接

    zsbfree 2010-04-29 21:28:20

    老赵,不用再理会 mcpssx这个人 不是对他有意见,而是觉得他无理取闹。

  71. Mikeshi
    114.82.98.*
    链接

    Mikeshi 2010-04-30 21:55:38

    说到3.0,我发现微软好像有个3.0情结,很多软件都是3.0开始发威的,比如IE,DirectX等等,呵呵

  72. Daoen Pan
    77.6.5.*
    链接

    Daoen Pan 2010-05-01 07:29:18

    如果不需要跨平台,仅限于Windows的话,C#无疑是个不错的选择,完胜Java。

  73. 老赵
    admin
    链接

    老赵 2010-05-01 14:19:04

    @Daoen Pan

    mono也不错,我两年前就在生产环境上用了,现在案例更是很多,说mono不成熟基本都是在FUD,基本没听到过什么靠谱的理由。

  74. Daoen Pan
    77.6.5.*
    链接

    Daoen Pan 2010-05-01 18:20:26

    @老赵

    说mono不成熟真的都是在FUD吗?我没在实际项目中用过C#, 主要原因就是跨平台。公司里的一个同事以前试过用mono跑他的一个Web应用,没有成功,后来放弃了。很多.NET做的桌面程序都只有Windows版,比如Paint.NET. 说mono现在就成熟,是很难让信服的,即使说mono将来会很成熟,很多人也是不相信的。

  75. 老赵
    admin
    链接

    老赵 2010-05-01 19:25:51

    @Daoen Pan

    我都告诉你亲身使用情况了,也告诉你有很多真实案例了,你说Paint.NET只支持Windows,这很正常,任何一个个案它都有自己的选择么。每个Java项目都跨平台吗?比如依赖epoll,调用外部shell脚本的项目能直接跑在Win上吗?但这些都是个例,我可以举出更多支持mono的。你同事的问题是什么我不知道,我只知道2年前我就在生产环境上使用了,我现在这个博客也是ASP.NET MVC 2(自己简单修改再编译的版本) + mono 2.6 + Apache + Ubuntu Server,都是好好的。

    我来说点mono的现状吧:IronPython,IronRuby,DLR等等都在mono上跑的好好的,它们的测试用例都包含mono相关的内容,Mix10等技术大会上都宣传mono了,GSoC上有10个关于mono的项目,F#团队有跨平台的职位,主要工作便是为mono提供支持……

    说mono不成熟自然不会都是FUD,比如有人觉得不如Java或MS.NET成熟就是不成熟,有人说还不能跑.NET 4因此不成熟,有人说tail call支持不够因此不成熟……这些都是合适的,每个人都有自己的标准。但是,假如像你现在这样,使用缺少事实支撑的“纯推理”,连现状如何都不去搜索或去官网看一下,还说未来什么什么的……事实上,我见过的几乎所有说mono不成熟的情况都是没理由的纯推理,这不是FUD还能是什么啊。

  76. 链接

    driedbeef 2010-05-02 21:29:39

    关于mono的观点,偶支持赵姐夫。

    没有实际使用就没有发言权。

  77. wl.dai
    119.32.84.*
    链接

    wl.dai 2010-05-02 21:45:07

    JAVA确实让人很多地方让人恨的牙痒痒,我是从C#转JAVA的,C#里一个@""就可以跨行字符串定义,JAVA到现在只能靠+拼接起来,写多行字符串时那个痛苦,比如大型SQL,每次调试和改动都小心翼翼。JAVA要不是跨平台,真不如用C#。不过话说回来,制约dotnet发展的就是跨平台,dotnet做大型项目没问题,但windows server得花多少钱。Linux 用mono,留待检验。。。,JAVA 跨平台只能针对SUN JDK,换个Harmony 都不知道能否保证不出问题,毕竟要保证API CLASS的完整一致性和逻辑一致性太困难。

  78. 老赵
    admin
    链接

    老赵 2010-05-03 00:12:19

    @wl.dai

    我倒觉得Windows Server真不需要多少钱,贵的是SQL Server或其他App Server,呵呵。所以我一直支持把存储放在*nix下面的。

  79. wl.dai
    119.32.83.*
    链接

    wl.dai 2010-05-07 01:29:48

    App Server?微软的主要应用服务器不是和windows server集成在一块吗,不是指BizTalk等Server ,而是最常用的IIS,COM+,MSMQ等。一个windows server 不需要多少钱,100台,200台,更多呢,还不算CPU个数。当应用规模小的时候,商业数据库的成本可能是大头,当应用规模增大时,App Server的成本绝对是大头。所以在以前我用dotnet开发时,主要用dotnet开发后台的管理和运营平台,利用dotnet的开发高效率,但前端的高负荷高并发业务系统用linux和java,n台server load balance。 在通常的应用中,其实前端的业务系统不是开发工作量最大的部分,最大的开发工作量在业务的管理、运营、数据平台上,但后台应用不需要那么多的服务器,只要服务器管理调配得当,用dotnet开发后台系统是能节省不少开发成本的。

    BTW,我一直以来用的是oracle,用惯了oracle,真的很难再转换了,数据库的设计经验可能可以不区分数据库,但应用经验和使用技巧很难通用。ORM跨数据库是个神话,简单的update , insert , delete 没问题,但是靠这些就能开发系统?

  80. 老赵
    admin
    链接

    老赵 2010-05-07 09:10:20

    @wl.dai

    我说的贵的App Server,主要就是指跑SPS,BizTalk之类的了,这些其实比Windows Server要贵很多。其实你需要的服务器数量和你的业务量是一致的,我说Windows Server不贵也是这个原因。开个公司就知道,烧钱无比快,计算一下就知道Windows Service就算100台服务器,其实和业务规模相比就会发现真是小头。

    上面说得这些其实更多是针对Web 2.0项目说的,当然我的意思是用Windows Server做前端,后端存储用Linux。其实Windows Server也可以作负载均衡啊,方法一样的,我一直把Linix和Windows Server一起用。我常说的一句话就是,Software Stack那么长,没必要追求全Windows或全Linix的。

    PS:至于你说的Oracle,要说起来那才是烧钱的主啊,呵呵。

  81. hippo
    113.91.88.*
    链接

    hippo 2010-05-15 22:17:43

    隔了半个月再过来看,评论中就只有 mcpssx 来跟博主辩论,除此之外貌似真正玩 java 的人都还没过来留言,看来博主这个系列也没什么动力写下去了。

    顺便提提,我最近几天在写 java 一个项目的代码时不经意想起这篇文章,因为使用了 spring 依赖注入的自动装配,我的 actions 里的私有成员上的标注是这样的:

    private @Autowire MemberService memberService;
    
    private @Autowire BillService billService;
    

    想到 c# 的特性似乎只能这样写:

    [Autowire]
    protected MemberService memberService;
    
    [Autowire]
    protected BillService billService;
    

    不知道这一点算不算是 “java语言” 比 “c#语言”优美的一个特例呢

  82. 老赵
    admin
    链接

    老赵 2010-05-15 23:34:42

    @hippo

    我觉得真没什么区别,美观优美与否在这里更像是个人感觉。而且其实我第一篇文章都说了,我重视的是真正改变编程思维,引入有效的编程方式等方面的语言特性,你说的这个区别我实在不觉得有什么值得一提的。就像我不会讨论C#里可以用属性,而Java里只能用get/set方法一样,因为它们的区别不足以让人侧目。

    话说搞Java的人其实都知道Java的问题,想要为Java说好话的人其实自己底气也不足。这系列我会写完的,只是最近要换个胃口写点别的,呵呵。

  83. 链接

    edpzjh 2010-05-18 23:03:36

    根本没有必要比,java是跨平台的,dotnet可以吗,别跟我说什么mono

  84. 老赵
    admin
    链接

    老赵 2010-05-18 23:09:33

    @edpzjh

    1. 回帖前看贴很困难吗?您这基本素质啊……
    2. 根本没有必要比,dotnet写winform又快又方便,java可以吗?别跟我说什么跨平台。
  85. StrongBird
    152.62.44.*
    链接

    StrongBird 2010-06-08 11:03:44

    个人认为拿.NET和Java做比较,侧重点还是应该放在“生产效率”上。毕竟这2个平台推出的初衷就是提高生产效率。

  86. fyhao
    118.101.146.*
    链接

    fyhao 2010-11-22 19:01:36

    以前学校教 asp.net 的时候所教的都是非常基础的东西。 简单的SQL调用,甚至是拖曳的。 当然我做Project的时候,由于已学过Java的ORM,还要慢慢打SQL会觉得很麻烦。 所以查找了一下C#.NET资源,找到了LINQ,就学习了。 LINQ,很好用,可以直接query object list出来,而且更加容易manage。 asp.net 到处都是扩展性,要做什么,哪里都可以 code 出来。 当然,我使用 asp.net 开发的时候,主要都是在 code,很少用拖曳控件的。 但是,由于拥有 Sun Cert,我未来工作还是会走 Java 路线,再来看看会不会像老赵一样投奔 MS。

  87. Tiger Soldier
    67.188.179.*
    链接

    Tiger Soldier 2013-03-24 04:59:37

    两年前看了赵姐夫这篇,当时对Java和C#没有接触,也没什么感想。现在工作使用Java,对Java的annotation有了一定的了解。老赵文中没有提到annotation修饰函数以外的用法。annotation修饰对象的数据成员和函数的参数在实践中经常用到,前者可以在创建mock对象时省几个字(如Mockito的Mock annotation),后者被guice用于依赖注入的binding。不知C#的attribute是否也可以修饰field和参数,是否有类似的实践运用?

  88. 老赵
    admin
    链接

    老赵 2013-03-24 11:29:54

    @Tiger Soldier

    你说的这些都是常见用法,属于最基础的……

  89. 链接

    isee 2013-10-07 16:29:42

    不知道是对。net的Annotation 不了解还是怎么,完全没看出lz说的 .net 比java的 Annotation 有什么高明之处。

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

发表回复

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

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

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

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

使用Live Messenger联系我