Java annotation: Difference between revisions

Content deleted Content added
Tags: Reverted section blanking blanking Mobile edit Mobile web edit
m Reverted edits by 2C0F:F5C0:44F:54F3:68EF:7DB0:5656:B58D (talk): unexplained content removal (HG) (3.4.10)
Line 80:
 
=== Custom annotations ===
 
Annotation type declarations are similar to normal interface declarations. An at-sign (@) precedes the [[Reserved word|keyword]] "interface".
 
<syntaxhighlight lang=Java>
// @Twizzle is an annotation to method toggle().
@Twizzle
public void toggle() {
}
 
// Declares the annotation Twizzle.
public @interface Twizzle {
}
</syntaxhighlight>
 
Annotations may include a set of key-value pairs, which are modeled as methods of the annotation type. Each method declaration defines an element of the annotation type. Method declarations must not have any parameters or a throws clause. Return types are restricted to [[Primitive data type|primitives]], [[String (computer science)|String]], Class, [[Enumerated type|enums]], annotations, and [[Array data type|arrays]] of the preceding types. Methods can have [[Default (computer science)|default values]].
 
<syntaxhighlight lang=Java>
// Same as: @Edible(value = true)
@Edible(true)
Item item = new Carrot();
 
public @interface Edible {
boolean value() default false;
}
 
@Author(first = "Oompah", last = "Loompah")
Book book = new Book();
 
public @interface Author {
String first();
String last();
}
</syntaxhighlight>
 
Annotations themselves may be annotated to indicate where and when they can be used:
 
<syntaxhighlight lang=Java>
@Retention(RetentionPolicy.RUNTIME) // Make this annotation accessible at runtime via reflection.
@Target({ElementType.METHOD}) // This annotation can only be applied to class methods.
public @interface Tweezable {
}
</syntaxhighlight>
 
The compiler reserves a set of special annotations (including <code>@Deprecated</code>, <code>@Override</code> and <code>@SuppressWarnings</code>) for syntactic purposes.
 
Annotations are often used by [[software framework|frameworks]] as a way of conveniently applying behaviours to user-defined classes and methods that must otherwise be declared in an external source (such as an XML configuration file) or programmatically (with API calls). The following, for example, is an annotated [[Java Persistence API|JPA]] data class:
 
<syntaxhighlight lang=Java>
@Entity // Declares this an entity bean
@Table(name = "people") // Maps the bean to SQL table "people"
public class Person implements Serializable {
@Id // Map this to the primary key column.
@GeneratedValue(strategy = GenerationType.AUTO) // Database will generate new primary keys, not us.
private Integer id;
 
@Column(length = 32) // Truncate column values to 32 characters.
private String name;
 
public Integer getId() {
return id;
}
 
public void setId(Integer id) {
this.id = id;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
}
</syntaxhighlight>
 
The annotations are not method calls and will not, by themselves, do anything. Rather, the class object is passed to the [[Java Persistence API|JPA]] implementation at [[Run time (program lifecycle phase)|run-time]], which then extracts the annotations to generate an [[object-relational mapping]].
 
A complete example is given below:
 
<syntaxhighlight lang=Java>
package com.annotation;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,
ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,
ElementType.PACKAGE,ElementType.FIELD,ElementType.LOCAL_VARIABLE})
@Inherited
 
public @interface Unfinished {
public enum Priority { LOW, MEDIUM, HIGH }
String value();
String[] changedBy() default "";
String[] lastChangedBy() default "";
Priority priority() default Priority.MEDIUM;
String createdBy() default "James Gosling";
String lastChanged() default "2011-07-08";
}
</syntaxhighlight>
 
<syntaxhighlight lang=Java>
package com.annotation;
 
public @interface UnderConstruction {
String owner() default "Patrick Naughton";
String value() default "Object is Under Construction.";
String createdBy() default "Mike Sheridan";
String lastChanged() default "2011-07-08";
}
</syntaxhighlight>
 
<syntaxhighlight lang=Java>
package com.validators;
 
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
 
import com.annotation.UnderConstruction;
import com.annotation.Unfinished;
import com.annotation.Unfinished.Priority;
import com.util.Util;
 
@UnderConstruction(owner="Jon Doe")
public class DateValidator implements Validator {
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
String date = (String) value;
String errorLabel = "Please enter a valid date.";
if (!component.getAttributes().isEmpty()) {
errorLabel = (String) component.getAttributes().get("errordisplayval");
}
 
if (!Util.validateAGivenDate(date)) {
@Unfinished(changedBy = "Steve",
value = "whether to add message to context or not, confirm",
priority = Priority.HIGH
)
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary(errorLabel);
message.setDetail(errorLabel);
throw new ValidatorException(message);
}
}
}
</syntaxhighlight>
 
== Processing ==