`
RednaxelaFX
  • 浏览: 3049620 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

C# attribute和Java annotation……

阅读更多
呃,今天感觉就被问了一个真的细到点上的问题,但我就正好不会。我还真是没自定义过Java的annotation,虽然没少用别人定义好的。
真糟糕,赶紧简单笔记一下。至少要保持最低限度的熟练……Java啊 T T

Java与C#都从一开始就强调程序的模块化,所以写出来的程序不但包括代码逻辑,还包括类型信息等“元数据”。Java早期版本只支持有限的几种元数据,用户无法自定义新的元数据类型;后来者C#则从一开始就在支持内建attribute的同时支持用户定义的attribute,为程序在运行时提供更多信息。从Java 5开始,Java添加了一些内建元数据类型,并且开始以annotation的形式支持用户定义的元数据。这样,在Java和C#中,用户都可以通过元数据来扩展语言,为语言提供更丰富的语义。

C#里要自定义attribute类型,可以直接或间接继承System.Attribute类,并通过AttributeUsageAttribute来指定attribute的应用范围,然后像定义普通的public类一样定义attribute的内容。
指定应用范围的AttributeTargets有以下成员:
MSDN 写道
Assembly Attribute can be applied to an assembly.
Module Attribute can be applied to a module.
Class Attribute can be applied to a class.
Struct Attribute can be applied to a structure; that is, a value type.
Enum Attribute can be applied to an enumeration.
Constructor Attribute can be applied to a constructor.
Method Attribute can be applied to a method.
Property Attribute can be applied to a property.
Field Attribute can be applied to a field.
Event Attribute can be applied to an event.
Interface Attribute can be applied to an interface.
Parameter Attribute can be applied to a parameter.
Delegate Attribute can be applied to a delegate.
ReturnValue Attribute can be applied to a return value.
GenericParameter Attribute can be applied to a generic parameter.
All Attribute can be applied to any application element.

一个简单的attribute的例子:
using System;

// define a custom attribute
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class LazyPopulateAttribute : Attribute {
    Type _propType;
    
    public LazyPopulateAttribute(Type propType) {
        _propType = propType;
    }
    
    public Type PropertyType {
        get { return _propType; }
    }
}


public class Singleton {
    static Singleton _instance;
    
    private Singleton() { }
    
    // use the custom attribute
    [LazyPopulate(typeof(Singleton))]
    public static Singleton Instance {
        get { return _instance; }
    }
}

static class Program {
    static void Main(string[] args) {
        var instance = Singleton.Instance;
        // ...
    }
}

上面的代码光是这么写的话,_instance没人赋过值,用起来显然有问题。但我们可以写一个程序在postbuild时分析程序集,提取出其中的attribute,并且让LazyPopulateAttribute指定的属性展开为典型的double-check初始化,Instance展开后应该变为:
public static Singleton Instance {
    get {
        var instance = _instance;
        if (null == instance) {
            lock(_lockObj) { // _lockObj是应该生成的成员
                  if (null == _instance) {
                    _instance = instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

在运行时通过反射,PropertyInfo.GetCustomAttributes()就可以得到针对property的attribute信息。具体要如何实现这个例子里的postbuild处理,下一篇再写。

Java方面,支持3种内建的annotation,包括@Override、@Deprecated、@SuppressWarnings。
指定应用范围的ElementType枚举类型有以下成员:
Javadoc 写道
ANNOTATION_TYPE Annotation type declaration
CONSTRUCTOR Constructor declaration
FIELD Field declaration (includes enum constants)
LOCAL_VARIABLE Local variable declaration
METHOD Method declaration
PACKAGE Package declaration
PARAMETER Parameter declaration
TYPE Class, interface (including annotation type), or enum declaration

在Java中自定义annotation类型的方法很简单,跟定义接口类似。使用@interface关键字来声明annotation类型,然后像声明方法一样声明其中的成员。与定义接口不同的是,annotation类型的成员可以带有default默认值声明。
public @interface NotImplemented {
    public enum Severity { CRITICAL, HIGH, MEDIUM, LOW, NONE }
    Severity severity() default Severity.NONE;
}


要说C# attribute跟Java annotation有什么关系,相同点是它们都是元数据的载体,差别恐怕主要在于两者的可应用范围不同了。可以看到,两者受到C#和Java语言本身的差异的影响,可应用的范围已经有所不同,例如C#可以对程序集或者模块应用attribute,但不能对命名空间应用;Java可以对包应用annotation,但不能对例如说JAR文件之类的不属于Java语言本身所支持的组织范围应用。
除去语言差异的影响,Java annotation有一个显著的特点就是它可以限定在别的annotation类型的定义上应用,也就是@Target({ElementType.ATTRIBUTE})。Java的@interface声明是extends java.lang.annotation.Annotation的语法糖,所以有@Target({ElementType.TYPE})的annotation也可以应用在annotation类型的定义上。在C#中,有[AttributeUsage(AttributeTarget.Class)]的attribute可以应用在任意类的定义上,而attribute本身就是个普通的类,所以自然也可以应用。不过在C#里无法直接定义出只能作用于attribute类型定义上的attribute,也就是说没有@Target({ElementType.ATTRIBUTE})的对应物,因而无法直接定义出专用的meta-annotation。这应该算是两者最大的区别了吧?
还有一个差异:C#的attribute总是能带到运行时的;Java的annotation则可以选择RetentionPolicy,可以是CLASS、RUNTIME或者SOURCE,所以不一定会带到运行时,甚至不一定会带到编译出来的.class文件里。javac可以挂上一些钩子,可以将annotation处理直接挂在编译过程中,所以SOURCE级的annotation很有意义。Project Lombok把这种能力发挥到了极致……最近不停看到它的消息,但一直没深入调查,真是罪过啊 =v=

不知道今天被问孤城的问题这样解答算不算对呢……?
说真的,上面提到的两个差异里,第二个我是前几天才刚看了一次的,不过被问的时候没想起来 T T 而第一个差异我一直没从“限制”的角度看,如果从“所有可应用范围”来看的话,我觉得还是C#的attribute范围大些,所以也是这么回答的。仔细想想,其实很难说谁大谁小,只能说设计得比较不同……
分享到:
评论
4 楼 RednaxelaFX 2009-09-08  
night_stalker 写道
遥想当年,我们用的教材还是 Thinking In Java 第二版,Eclipse 还是 IBM 的,Sun 忙着推广 Sun One Studio(现在死掉了?),也装过微软送的 VS 2003 光盘 ……

我是装过微软送的Visual Studio 2005 Beta……刚进大学的时候2003还是主流。Sun One Studio还没挂吧,之前我想过下载但是要注册就懒了。Eclipse还在IBM的时候不是叫Visual Age for Java么……?
3 楼 night_stalker 2009-09-08  
遥想当年,我们用的教材还是 Thinking In Java 第二版,Eclipse 还是 IBM 的,Sun 忙着推广 Sun One Studio(现在死掉了?),也装过微软送的 VS 2003 光盘 ……
2 楼 RednaxelaFX 2009-09-08  
Saito 写道
    暴走吧. .孤城在大学期间一直是做c#的 .. 来淘宝才转java的. 不做c#很多年了已经.. 那时的c#应该和java差不多吧.

Java 5也已经很多年了……要知道我刚进大学的时候Java 5(“Tiger”)就已经炒得很热了 T T
1 楼 Saito 2009-09-08  
    暴走吧. .孤城在大学期间一直是做c#的 .. 来淘宝才转java的. 不做c#很多年了已经.. 那时的c#应该和java差不多吧.

相关推荐

    C#的Attribute

    C#的Attribute

    .net中attribute实现方法调用拦截(就是aop)

    标签中的"C#"表明我们讨论的是.NET框架中的C#语言,"attribute"对应上面提到的特性,"aop"则是本文的核心——面向切面编程。在实际项目中,利用Attribute实现AOP可以帮助我们编写更加整洁、可维护的代码,同时减少...

    c#的attribute实例源码

    C#的Attribute是一种元数据,它允许我们向代码添加额外的信息,这些信息可以在编译时或运行时被程序集、编译器、反射或其他工具使用。Attribute不是代码的一部分,它们不直接影响程序的执行,但提供了方便的方式来...

    C#和JAVA的区别总结

    C#的Attribute比Java的Annotation功能强大,但Java结合AOP框架也能实现类似功能。 14. 指针: C#提供unsafe关键字支持指针操作,而Java不直接支持指针。 15. 输入输出: C#的输入通常使用int.Parse(Console....

    java代码转c#

    6. **注解与特性**:Java有注解(Annotation),C#有特性(Attribute),两者都是元数据,但C#的特性可以用于运行时反射。 7. **垃圾回收**:虽然两者都有自动垃圾回收机制,但C#提供了更多的控制选项,如`GC....

    C#特性Attribute的实际应用之:为应用程序提供多个版本

    在标题“C#特性Attribute的实际应用之:为应用程序提供多个版本”中,我们可以看到一个具体的应用场景,即利用特性来区分和管理应用程序的不同版本,如体验版和完整功能版。 首先,我们来看如何创建自定义特性。在...

    c#和java读写xml辅助工具

    本教程将详细介绍如何使用C#和Java来创建高效的XML辅助工具,以简化XML文件的处理。 ### C# XML处理 在C#中,我们可以利用.NET Framework提供的`System.Xml`命名空间中的类来读写XML。以下是一些关键类: 1. **...

    使用Attribute语法优化Java

    在讨论如何使用属性(Attribute)语法优化Java之前,我们首先要了解什么是属性文法。属性文法是一种形式化的方法,用于定义和处理语言的语法规则和与之相关的属性。这种技术是编译原理中的一部分,它允许程序员和...

    c#中的特性(attribute)+反射的一个例子

    在C#编程语言中,特性(Attribute)是一种元数据,它可以提供有关代码的附加信息,这些信息可以在编译时或运行时被程序访问。特性允许程序员向类、方法、属性等添加自定义标记,以便在后期处理中进行特定操作。另一...

    C# to Java Converter.zip

    9. **特性与注解**:C#的特性(Attribute)对应Java的注解(Annotation),转换时需要保持这些元数据的正确性。 10. **编译器特性**:C#的一些特性如默认接口实现、模式匹配等Java尚未完全支持,转换时可能需要额外...

    C#、java命名规则和开发习惯

    这里我们将深入探讨C#和Java这两种广泛使用的编程语言的命名规范和最佳实践。 首先,让我们关注C#的命名规则: 1. 类型(类、接口等)的命名应使用PascalCase,例如`TextBox`和`ICompare`。 2. 局部变量和方法参数...

    使用C#的Attribute(特性)实现一个简单的ORM

    【内容概要】:在C#中通过学习使用Attribute,实现一个简单的ORM框架。里面主要有两部分的内容,学习使用Attribute获得设定值;学习通过反射获取属性的值 【适应人群】:初级工程师。但需要对反射、Attribute有一定...

    C# 特性(Attribute).docx

    在C#编程语言中,特性(Attribute)是一种元数据,它可以提供附加信息给编译器、运行时环境或者工具链,以影响代码的行为或者提供额外的描述。这些特性是类的实例,它们属于.NET框架的一部分,允许程序员在不改变...

    一个实现IOC的小框架 利用Attribute简化Unity框架IOC注入

    Attribute在.NET中是一种元数据,可以附加到程序元素(如类、方法、属性等)上,提供额外的信息,通常用于运行时反射和自定义行为。 在Unity中,我们通常需要在容器中注册类型映射,然后在需要的地方通过依赖解析...

    面试题集锦(C#,java)

    - C#使用`attribute`来标记元数据,Java使用注解(annotation)实现类似功能。 13. **泛型**: - 两者的泛型机制类似,但C#支持更广泛的泛型应用,如泛型接口、泛型委托等。 14. **位移操作**: - C#提供了`>>>...

    Attribute标记属性_资料收集

    在C#中,我们使用`[Attribute]`语法来应用一个Attribute实例到我们的代码元素上。 二、创建自定义Attribute 要创建自定义Attribute,我们需要继承自`System.Attribute`基类,并定义所需的属性和方法。例如,我们...

    css中文手册、帮助文档

    本手册针对的是已有一定网页设计制作经验的读者。其目的是提供最新最全的样式表内容的快速索引及注释。... 3、属性选择符 Attribute Selectors ……………… …… 还有很多其它的内容,恕不描述了。

    Property和Attribute的区别

    "Property和Attribute的区别" 在面向对象编程(Object-Oriented Programming)中,Property和Attribute都是常用的概念,但是它们之间存在着本质的区别。Property是指类向外提供的数据区域,是智能的字段,其中有get...

    C#中Property和Attribute的区别实例详解

    本文实例分析了C#中Property和Attribute的区别。分享给大家供大家参考。具体分析如下: 在C#中有两个属性,分别为Property和Attribute,两个的中文意思都有特性、属性之间,但是用法上却不一样,为了区别,本文暂把...

    C#基础--Attribute(标签) 和 reflect(反射) 应用

    在.NET框架中,C#是一种强大的面向对象的编程语言,其特性丰富,其中包括了Attribute(属性)和Reflect(反射)这两个重要概念。这两者在实际开发中有着广泛的应用,能够帮助程序员实现元数据的标记、运行时代码的...

Global site tag (gtag.js) - Google Analytics