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

上一篇文章里我谈了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) { ... }
}

时间: 2024-08-19 04:14:05

Why Java Sucks and C# Rocks(3):Attribute与Annotation的相关文章

Why Java Sucks and C# Rocks(1):比较的意义与目的

为什么是Java? 这个系列我将详细比较C#和Java--语言,而不关Java平台任何事情.其实这本不想强调这一点,因为语言和平台之间是没有任何可比 性的.因为C#明显只是一门语言,因此根据"类型推断",则Java也应该是"语言"类型才对.因此,我在标题中就不想加入"Language "这样较长的单词了,累赘啊! 那么,我为什么选中Java来和C#进行比较,而不是其他语言呢?原因很多,主要有以下几点. 首先,Java语言足够热门.看看TIOBE语

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

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

分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

在许多年前,"语言"就等同于"平台",例如C,C++以及最早的Ruby和Python等等.但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多.再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂.技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.简单地说,如今的观念,一定要从"语言即平台"切换成"语言及平台",当分清"语言"和&quo

一起谈.NET技术,分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

在许多年前,"语言"就等同于"平台",例如C,C++以及最早的Ruby和Python等等.但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多.再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂.技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.简单地说,如今的观念,一定要从"语言即平台"切换成"语言及平台",当分清"语言"和&quo

JAVA与XML 之JDOM

dom|xml 在 JDOM 中,XML 元素就是 Element 的实例,XML 属性就是 Attribute 的实例,XML 文档本身就是 Document 的实例.    因为 JDOM 对象就是像 Document.Element 和 Attribute 这些类的直接实例,因此创建一个新 JDOM 对象就如在 Java 语言中使用 new 操作符一样容易.JDOM 的使用是直截了当的.    JDOM 使用标准的 Java 编码模式.只要有可能,它使用 Java new 操作符而不故弄玄

Java Map 集合类简介

集合 java.util 中的集合类包含 Java 中某些最常用的类. 最常用的集合类是 List 和 Map. List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建.存储和操作任何类型对象的元素列表. List 适用于按数值索引访问元素的情形. Map 提供了一个更通用的元素存储方法. Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值. 从概念上而言,您可以将 List 看作是具有数值键的 M

dom4j(Java code)

import java.io.File; import java.io.FileWriter; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute;import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat;import

在java中使用dom4j解析xml(示例代码)_java

虽然Java中已经有了Dom和Sax这两种标准解析方式 但其操作起来并不轻松,对于我这么一个初学者来说,其中部分代码是活生生的恶心 为此,伟大的第三方开发组开发出了Jdom和Dom4j等工具 鉴于目前的趋势,我们这里来讲讲Dom4j的基本用法,不涉及递归等复杂操作 Dom4j的用法很多,官网上的示例有那么点儿晦涩,这里就不写了 首先我们需要出创建一个xml文档,然后才能对其解析 xml文档: 复制代码 代码如下: <?xml version="1.0" encoding=&quo

JAVA对XML文件的读写(有具体的代码和解析)

XML 指可扩展标记语言(EXtensible Markup Language),是独立于软件和硬件的信息传输工具,应用于 web 开发的许多方面,常用于简化数据的存储和共享. xml指令 处理指令,简称PI (processing instruction).处理指令用来指挥解析引擎如何解析XML文档内容. 以下为例: 进入主题了 首先要有一个xml文件为名字为emplist.xml内容如下 <?xml version="1.0" encoding="UTF-8&quo