54

I have a Java library I'm considering porting to C#. The Java library makes extensive use of annotations (at both build time and run time.)

I've never used C# attributes, but understand that they are the rough equivalent of Java annotations.

If I proceed with the port using attributes to replace annotations, what do I need to know? What's going to be the same? Different? What's going to bite me?

Jared
  • 25,520
  • 24
  • 79
  • 114

4 Answers4

31

Control over when your metadata is made accessible is different between the two languages.

Java provides the java.lang.annotation.Retention annotation and java.lang.annotation.RetentionPolicy enum to control when annotation metadata is accessible. The choices vary from Runtime (most common - annotation metadata retained in class files), to Source (metadata discarded by compiler). You tag your custom annotation interface with this - for example:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.CLASS)
public @interface TraceLogging {
  // etc
}

would allow you to reflect on your custom TraceLogging annotation at runtime.

C# uses the ConditionalAttribute attribute that is driven from compile time symbols. So the analogous example in C# is:

[Conditional("TRACE")]
public class TraceLoggingAttribute : Attribute
{
  // etc
}

which would cause the compiler to spit out the metadata for your custom TraceLogging attribute only if the TRACE symbol was defined.

NB. attribute metadata is available at runtime by default in C# - this is only needed if you want to change that.

serg10
  • 31,923
  • 16
  • 73
  • 94
  • 4
    +1: Retention into runtime will be important for the port. thanks. – Jared Feb 17 '09 at 16:10
  • 1
    yw. Note that as per my last edit, you will be able to reflect on your custom C# attribute if you do nothing. This mechanism allows you to turn off that default behaviour, which is probably of limited utility to be honest. – serg10 Feb 17 '09 at 17:10
20

One important aspect of Java annotations which I haven't looked at in detail yet: you can write code which uses annotations within javac (as of Java 6, I believe) as a form of metaprogramming.

PostSharp allows something similar, admittedly.

(That's far from the only difference, but it's all I have time for right now.)

Gili
  • 86,244
  • 97
  • 390
  • 689
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • While I've eyed apt, I don't actually use the APT API - my code uses reflection (and a doclet) to do its work (as opposed to using APT to generate an set of intermediate stuff during the build.) So, I think I'm not concerned about this missing capability. Keep 'em coming :) – Jared Feb 16 '09 at 18:36
  • Jon - just pinging you to let you know that there's a 100 point bounty on this question - if you have more time to spend giving a more complete answer (and the points are worth it) - I'd certainly welcome that :). Thanks! – Jared Mar 19 '09 at 19:02
  • Hmm... I'll see if I can can find time to look into it more. I may well not have time though :( – Jon Skeet Mar 26 '09 at 13:39
16

One interesting difference is that C# allows module and assembly level attributes. These are applied to your module or assembly and are available via reflection in the normal way. Java does not provide reflection on a jar file, so jar level annotations are not possible.

In fact this is quite common as Visual Studio a file called AssemblyInfo.cs at the root project level which contains, for example:

[assembly: AssemblyVersionAttribute("1.2.3.4")]
[assembly: AssemblyTitleAttribute("My project name blah blah")]
...

There is no equivalent jar level annotation in Java (although since jdk5, there is a little used package level annotation mechanism - thanks to mmeyers for pointing that one out)

Community
  • 1
  • 1
serg10
  • 31,923
  • 16
  • 73
  • 94
3

Following up to what Jon said...

Both Java 5 and Java 6 allow metaprogramming. Java 5 uses a separate apt tool; Java 6 integrates it into the compiler. (Though the Java 5 apt is still available in Java 6)

Unfortunately each uses a different API.

I'm currently using the Java 5 API for my Bean annotations

See http://code.google.com/p/javadude/wiki/Annotations for an example (NOTE: I'm currently making some major updates, some of which change the API.)

Very cool stuff... -- Scott

Scott Stanchfield
  • 29,742
  • 9
  • 47
  • 65