<rdf:RDF
    xmlns:s='http://snipsnap.org/rdf/snip-schema#'
    xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
    xml:base='http://www.pabrantes.net/blog/rdf'>
    <s:Snip rdf:about='http://www.pabrantes.net/blog/rdf#start/2006-07-04/1'
         s:name='start/2006-07-04/1'
         s:cUser='pabrantes'
         s:oUser='pabrantes'
         s:mUser='pabrantes'>
        <s:content>1 Java Programming: Doing your own annotations {anchor:Java Programming: Doing your own annotations}&#xD;&#xA;With the release of Java 5 a new feature called annotation showed up. Probably you have already seen it, or even used it. &#xD;&#xA;&#xD;&#xA;&#xD;&#xA;Basically annotations are metadata you insert in you classes and can be identified by the keyword __@annotation_name__. \\&#xD;&#xA;Maybe you&apos;ve already used java built-in annotations, such as __@Deprecated__ or __@Override__, but I&apos;m not gonna talk about the existing annotations, I&apos;m writing about how you can create your custom annotation, so let&apos;s start.&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;First of all you have to ask yourself the following:&#xD;&#xA;&#xD;&#xA;1. What will be the name of the annotation&#xD;&#xA;1. What arguments will it receive&#xD;&#xA;&#xD;&#xA;Let&apos;s now build 2 annotations, one without any arguments - which is commonly called a marker - and one with 2 arguments.&#xD;&#xA;&#xD;&#xA;In the first case, programming a marker is as simple as:&#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;package net.pabrantes.annotations&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;public @interface MyMarker {&#xD;&#xA;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;Now after compiling it, you can use the new annotation referring to it as __@MyMarker__. Although, this being a marker we want to specify that it should be discarded by the compiler. That can be done setting up the {link:__retention policy__|url=http://download.java.net/jdk6/docs/api/java/lang/annotation/Retention.html|newWindow=true}.&#xD;&#xA;&#xD;&#xA;You can set the retention policy to retain the annotation only at the source code by doing the following:&#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;package net.pabrantes.annotations&#xD;&#xA;&#xD;&#xA;@Retention(java.lang.annotation.RetentionPolicy.SOURCE)&#xD;&#xA;public @interface MyMarker {&#xD;&#xA;&#xD;&#xA;}&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;Yes, you just have annotated an annotation! Below you can find a description of each value that the retention policy can take.&#xD;&#xA;&#xD;&#xA;{table}&#xD;&#xA;Policy Name | Policy |&#xD;&#xA;SOURCE | Annotation is discarded at compile time |&#xD;&#xA;CLASS | Annotation goes into class file but the virtual machine does not retain it |&#xD;&#xA;RUNTIME | Annotation goes into class file and and retained by virtual machine. They can then be read by reflection API. | &#xD;&#xA;&#xD;&#xA;{table}&#xD;&#xA;&#xD;&#xA;You can also annotate an annotation to tell what elements can be annotated, but we will get there later. First, let&apos;s build our annotation with two parameters.\\&#xD;&#xA;Code follows:&#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;package net.pabrantes.annotations&#xD;&#xA;&#xD;&#xA;public @interface MyAnnotation {&#xD;&#xA;&#xD;&#xA;public enum SomeSortOfEnum { VALUE1, VALUE2 };&#xD;&#xA;&#xD;&#xA;public String parameter1();&#xD;&#xA;public SomeSortOfEnum parameter2();&#xD;&#xA;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;So now you can annotate your code doing the following: &#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;@MyAnnotation(parameter1=&quot;a string&quot;, parameter2=SomeSortOfEnum.VALUE1 }&#xD;&#xA;public void method(...) { ... }&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;But imagine that you want to allow the programmers to only specify parameter2, and that if no parameter1 is specified it defaults to __&quot;My String&quot;__. To do that we have to adjust a bit our annotation source code. &#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;package net.pabrantes.annotations&#xD;&#xA;&#xD;&#xA;public @interface MyAnnotation {&#xD;&#xA;&#xD;&#xA;public enum SomeSortOfEnum { VALUE1, VALUE2 };&#xD;&#xA;&#xD;&#xA;public String parameter1() default &quot;My String&quot; ;&#xD;&#xA;public SomeSortOfEnum parameter2();&#xD;&#xA;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;Finally imagine that you want to allow the use of this annotation only in methods of a class and the constructors. To do this you have to set the target elements, and that is done using another annotation, called __@Target__.\\&#xD;&#xA;Here is how it can be done:&#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;&#xD;&#xA;package net.pabrantes.annotations&#xD;&#xA;&#xD;&#xA;import static java.lang.annotation.ElementType.METHOD;&#xD;&#xA;import static java.lang.annotation.ElementType.CONSTRUCTOR;&#xD;&#xA;&#xD;&#xA;@Target({METHOD,CONSTRUCTOR})&#xD;&#xA;public @interface MyAnnotation {&#xD;&#xA;&#xD;&#xA;public enum SomeSortOfEnum { VALUE1, VALUE2 };&#xD;&#xA;&#xD;&#xA;public String parameter1() default &quot;My String&quot; ;&#xD;&#xA;public SomeSortOfEnum parameter2();&#xD;&#xA;&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;{code}&#xD;&#xA;&#xD;&#xA;Below you can find a table with all the values of {link:ElementType|url=http://download.java.net/jdk6/docs/api/java/lang/annotation/ElementType.html|newWindow=true}.&#xD;&#xA;&#xD;&#xA;{table}&#xD;&#xA;Type | Description |&#xD;&#xA;ANNOTATION_TYPE  | Declares that the annotation is used to annotate other annotations |&#xD;&#xA;CONSTRUCTOR | Declares that the annotation is used to annotate constructors |&#xD;&#xA;METHOD | Declares that the annotation is used to annotate methods in the class, constructors are not included in this type | &#xD;&#xA;FIELD | Declares that the annotation is used to annotate field declarations |&#xD;&#xA;LOCAL_VARIABLE | Declares that the annotation is used to annotate a local variable|&#xD;&#xA;PARAMETER | Declares that the annotation is used to annotate a parameter | &#xD;&#xA;PACKAGE | Declares that the annotation is used to annotate a package| &#xD;&#xA;TYPE | Declares that the annotation is used to annotate a Class, interface or Enum| &#xD;&#xA;{table}&#xD;&#xA;&#xD;&#xA;After reading this post I think it&apos;s safe to say that you have the necessary knowledge to write your own annotations, although, don&apos;t start going nuts writing custom annotations for everything. \\&#xD;&#xA;Before writing your new custom annotation ask yourself if it&apos;s really needed, otherwise you have the risk of excess of annotations in your code, which as you can imagine is not good at all.&#xD;&#xA;&#xD;&#xA;</s:content>
        <s:mTime>2006-07-04 00:56:10.549</s:mTime>
        <s:cTime>2006-07-04 00:53:51.594</s:cTime>
        <s:comments>
            <rdf:Bag>
                <rdf:li>
                    <s:Comment rdf:about='http://www.pabrantes.net/blog/rdf#comment-start/2006-07-04/1-1'
                         s:name='comment-start/2006-07-04/1-1'
                         s:cUser='MANOWAR^'
                         s:oUser='MANOWAR^'
                         s:mUser='MANOWAR^'>
                        <s:content>Ok this is in no shape way or form related to the cool ass article about annotations (which btw now I am able to use myself :) ) but with the fact that the site (or actually the code blocks) looks bad in Firefox on OS X (10.4.7). The code sticks together (words run into each other or overlap each other) please advise :P :)</s:content>
                        <s:mTime>2006-07-06 18:34:51.636</s:mTime>
                        <s:cTime>2006-07-06 18:34:51.456</s:cTime>
                        <s:commentedSnip rdf:resource='http://www.pabrantes.net/blog/rdf#start/2006-07-04/1'/>
                    </s:Comment>
                </rdf:li>
                <rdf:li>
                    <s:Comment rdf:about='http://www.pabrantes.net/blog/rdf#comment-start/2006-07-04/1-2'
                         s:name='comment-start/2006-07-04/1-2'
                         s:cUser='pabrantes'
                         s:oUser='pabrantes'
                         s:mUser='pabrantes'>
                        <s:content>Well I&apos;m glad you liked the post and taught you something... Finally I wrote something useful! ~~laugh~~&#xD;&#xA;&#xD;&#xA;Anyway regarding the code blocks I find that really strange, since I&apos;m also using Firefox (1.5.0.4) and OS X (10.4.7) and the code looks excellent. Maybe it&apos;s the font you are using... Don&apos;t really know, since I&apos;m not that UI guy... But sounds like a CSS problem.&#xD;&#xA;&#xD;&#xA;My default font is Times size 16. If you haven&apos;t that please retry...Also if it&apos;s not, it&apos;s better to report such behaviour to the snipsnap developers:&#xD;&#xA;&#xD;&#xA;* Matthias L. Jugel (matthias.jugel -at- first.fraunhofer.de)&#xD;&#xA;* Stephan J. Schmidt (stephan.schmidt -at- first.fraunhofer.de)&#xD;&#xA;&#xD;&#xA;Send them a screenshot along with your font information. And it would rock if you spotted the problem in the CSS. &#xD;&#xA;</s:content>
                        <s:mTime>2006-07-06 20:42:11.436</s:mTime>
                        <s:cTime>2006-07-06 20:42:11.355</s:cTime>
                        <s:commentedSnip rdf:resource='http://www.pabrantes.net/blog/rdf#start/2006-07-04/1'/>
                    </s:Comment>
                </rdf:li>
            </rdf:Bag>
        </s:comments>
        <s:snipLinks>
            <rdf:Bag>
                <rdf:li rdf:resource='http://www.pabrantes.net/blog/rdf#start/2008-03-24/1'/>
                <rdf:li rdf:resource='http://www.pabrantes.net/blog/rdf#pabrantes/post-history'/>
                <rdf:li rdf:resource='http://www.pabrantes.net/blog/rdf#start/2007-10-22/1'/>
                <rdf:li rdf:resource='#snipsnap-notfound'/>
                <rdf:li rdf:resource='#snipsnap-search'/>
                <rdf:li rdf:resource='#pabrantes'/>
            </rdf:Bag>
        </s:snipLinks>
        <s:attachments
             rdf:type='http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag'/>
    </s:Snip>
</rdf:RDF>
