Download presentation
Presentation is loading. Please wait.
Published byEugenia Agnes Warner Modified over 9 years ago
1
1 Java Programming II Annotations and Reflection
2
2 Java Programming II Contents Annotations Annotating Elements Restricting Annotation Applicability Retention Policies The Class Class Examples Reflection Annotation Queries The Modifier Class The Member classes
3
3 Java Programming II Annotations The source code for our program is usually accompanied by copious amounts of informal documentation that typically is contained within comments in the source code Many organizations have a standard preamble: copyright information, the programmers name, the date the class was created, etc. Other comments by external tools: version control in a source code management system, or deployment descriptors on how a class should be managed by an application server. Comments based annotation A better way to document the many annotations: to annotate the program elements directly using annotation types Another motivation: many APIs require a fair amount of boilerplate code. (For example, in order to write a JAX-RPC web service, you must provide a paired interface and implementation. ) This boilerplate could be generated automatically by a tool if the program were “decorated” with annotations indicating which methods were remotely accessible.
4
4 Java Programming II Annotations Provide data about a program that is not part of the program itself. Using annotation type to describe the form of the annotations. Uses of Annotation Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings. Compiler-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth. Runtime processing — Some annotations are available to be examined at runtime.
5
5 Java Programming II Annotations /*------------------------------ Created: Jan 31 2005 Created By: James Gosling Last Modified: Feb 9 2005 Last Modified By: Ken Arnold Revision: 3 ---------------------------------*/ public class Foo { // ….. } @interface ClassInfo { String created(); String createdBy(); String lastModified(); String lastModifiedBy(); int revision(); } @ClassInfo( created = “Jan 31 2005”, createdBy = “James Gosling”, lastModified =“Feb 9 2005”, lastModifiedBy =“Ken Arnold”, revision =3 ) public class Foo { // class definition… } Annotation Type Documentation Using Comments Using Annotation Annotation for the class Foo How to use Annotation 1. Define Annotation Type 2. Add Annotation using the type
6
6 Java Programming II Annotation Types @interface Revision { int major() default 1; int minor() default 0; } @interface ClassInfo { String created(); String createdBy(); String lastModified(); String lastModifiedBy(); Revision revision(); } @ClassInfo ( created = “Jan 31 2005”, createdBy = “James Gosling”, lastModified = “Feb 9 2005”, lastModifiedBy = “Ken Arnold”, revision = @Revision(major=3) ) public class Foo { // … } Constraint rules of the methods declared in an annotation type (elements of annotation type) The type of the element can only be a primitive type, String, enum, another annotation type, Class, or an array of the preceding types. Cannot declare any parameters. Cannot have a throws clause. Cannot define a type parameter, i.e cannot be a generic method. Initialization expression - Marker annotation: annotation type which has zero elements (ex) public @interface Preliminary { }
7
7 Java Programming II Annotation Used by Complier @Deprecated—the @Deprecated annotation indicates that the marked element is deprecated and should no longer be used. When an element is deprecated, it should also be documented using the Javadoc @deprecated tag. // Javadoc comment follows /** * @deprecated * explanation of why it was deprecated */ @Deprecated static void deprecatedMethod() { } } @Override—the @Override annotation informs the compiler that the element is meant to override an element declared in a superclass (overriding methods will be discussed in the the lesson titled "Interfaces and Inheritance"). @SuppressWarnings—the @SuppressWarnings annotation tells the compiler to suppress specific warnings that it would otherwise generate. In the example of the right site, a deprecated method is used and the compiler would normally generate a warning. In this case, however, the annotation causes the warning to be suppressed. @SuppressWarnings(deprecation) void useDeprecatedMethod() { objectOne.deprecatedMethod(); // deprecation warning suppressed }
8
8 Java Programming II Annotating Elements and Restricting Annotation Applicability Marker annotation or all its elements have default values @Deprecated public void badMethod() {/* … */} (an empty list of initializers) @Deprecated() public void badMethod() {/* … */} Array initializer expression @interface BugsFixed { String[] bugIds(); } @BugsFixed(bugIDs = {“1234”, “4567”}) or @BugsFixed(bugIDs = “4567”) When has only a single element (naming of the element is value), it allows for additional shorthand: @inteface BugsFixed { String[] value(); } @BugsFixed({“1234”,”4567”}) @BugsFixed(“4567”)
9
9 Java Programming II Retention Policies Annotation can serve many different purposes and may be intended for different readers (programmers, or a development tool, compiler, some tool that may need to extract the annotations from a binary representation of a class, and to be inspected at runtime) The Target annotation type Enum constant of ElementType : Represents the different kinds of program elements to which annotations can be applied. 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 Example @Target (ElementType.TYPE) @interface ClassInfo { String created(); String createdBy(); String lastModified(); String lastModifiedBy(); Revision revision(); } This will be applied to type declaration
10
10 Java Programming II Retention Policies Three Retention Policies Can be applied when the annotation can be accessed. (Used by @Retention type, Defined by the RetentionPolicy enum) SOURCE: Annotations exist only in the source file CLASS: preserved in the binary representation of the class, but not available at run time RUNTIME: must be available at runtime via the reflection mechanism Example @Retention(RetentionPolicy.RUNTIME)
11
11 Java Programming II The “Class” class The Class class defines these methods: getName – returns the (class) name getFields – returns all the public fields getMethods – returns all the public methods getPackage – returns the class’ package getSuperclass – returns the class’ superclass getConstructors – returns all the public constructors static Class forName(String className) - returns Class object Annotation[] getAnnotations() - returns all annotations present on this element.
12
12 Java Programming II Working with Annotations (I) A simple annotation-based test framework “Foo.java” import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface Test { } public class Foo { @Test public static void m1() { } public static void m2() { } @Test public static void m3() { throw new RuntimeException("Boom"); } public static void m4() { } @Test public static void m5() { } public static void m6() { } @Test public static void m7() { throw new RuntimeException("Crash"); } public static void m8() { } } “RunTests.java” import java.lang.reflect.*; public class RunTests { public static void main(String[] args) throws Exception { int passed = 0, failed = 0; for (Method m : Class.forName(args[0]).getMethods()) { if (m.isAnnotationPresent(Test.class)) { try { m.invoke(null); passed++; } catch (Throwable ex) { System.out.printf("Test %s failed: %s %n", m, ex.getCause()); failed++; } System.out.printf("Passed: %d, Failed %d%n", passed, failed); } Run: % java RunTests Foo Add “Test” Annotation
13
13 Java Programming II Working with Annotations (II) BugsFixedExample: Using Class and getAnnotation method of the “ClassInfo” class “MyFoo.java” import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface BugsFixed { String[] value(); } @BugsFixed( {"1234", "5678"} ) public class MyFoo { } “BugsFixedExample.java” public class BugsFixedExample { public static void main(String[] args) { Class cls = MyFoo.class; BugsFixed bugsFixed = (BugsFixed) cls.getAnnotation(BugsFixed.class); System.out.println(bugsFixed); String[] bugIds = bugsFixed.value(); for (String id : bugIds) System.out.println(id); } Run: % java BugsFixedExample
14
14 Java Programming II Documentation Comments A Simple Example /** * An Attr object defines an attribute as a * name/value pair, where the name is a String * and the value an arbitray Object. * * @version 1.1 * @author Plago * @since 1.0 */ public class Attr { /** The attribute name. */ private final String name; /** The attribute value. */ private Object value = null; /** * Crates a new attribute with the given name and an * initial value of null. * @see Attr#Attr(String,Object) */ public Attr(String name) { this.name = name; } /** * Creates a new attribute with the given name and * inital value. * @see Attr#Attr(String) */ public Attr(String name, Object value) { this.name = name; this.value = value; } /** Returns this attribute's name. */ public String getName() { return name; } /** Returns this attribute's value. */ public Object getValue() { return value; } /** * Sets the value of this attribute. Changes the * value returned by calls to {@link #getValue}. * @param newValue The new value for the attribute. * @return The Original value. * @see #getValue() */ public Object setValue(Object newValue) { Object oldVal = value; value = newValue; return oldVal; } /** * Returns a string of the form name=value. */ public String toString() { return name + "='" + value + "'"; } Run: % javadoc Attr.java
15
15 Java Programming II Reflection The reflection is to examine a type in detail. The reflection package : java.lang.reflect Reflection starts with a Class object A simple example of a “type browser”. import java.lang.reflect.*; import static java.lang.System.out; import static java.lang.System.err; public class SimpleClassDesc { public static void main(String[] args) { Class type = null; try { type = Class.forName(args[0]); } catch(ClassNotFoundException e) { err.println(e); return; } out.print("class " + type.getSimpleName()); Class superclass = type.getSuperclass(); if (superclass != null) out.println(" extends " + superclass.getCanonicalName()); else out.println(); Method[] methods = type.getDeclaredMethods(); for (Method m : methods) if (Modifier.isPublic(m.getModifiers())) out.println(" " + m); } Run: % java SimpleClassDesc Attr Result: class Attr extends java.lang.Object public java.lang.String Attr.getName() public java.lang.String Attr.toString() public java.lang.Object Attr.getValue() public java.lang.Object Attr.setValue(java.lang.Object) The source code is at the /home/course/java2/code/AnnotationReflection/ Argument: Attr.class
16
16 Java Programming II The Introspection Hierarchy Class Type ParameterizedType GenericArrayType TypeVariable WildcardType AnnotatedElement GenericDeclaration Member ConstructorMethodFieldPackage AccessibleObject
17
17 Java Programming II Type Tokens Type Token Each Class object for a reference type is of a parameterized type corresponding to the class it represents. (Ex: the type of String.class is Class ) A parameterized Class type is known as the type token for a given class The easiest way to obtain a type token is to use a class literal. import java.util.*; public class TypeTokenTest { public static void main(String[] args) { Class c1 = String.class; System.out.println("Result1 = " + c1.getClass()); String str = "Hello"; // Class c2 = str.getClass(); // error! Class c2 = str.getClass(); System.out.println("Result2 = " + c2); try { Class c3 = Class.forName("java.lang.String"); //valid Class c3 = Class.forName("java.lang.String"); //invalid System.out.println("Result3 = " + c3); } catch(ClassNotFoundException e) { System.err.println(e); return; } Exact type token How about this? Class c3 = Class.forName("java.lang.String").asSubclass(String.class); class literal
18
18 Java Programming II Class Inspection import java.lang.reflect.*; public class TypeDesc { public static void main(String[] args) { TypeDesc desc = new TypeDesc(); for (String name : args) { try { Class startClass = Class.forName(name); desc.printType(startClass, 0, basic); } catch (ClassNotFoundException e) { System.err.println(e); // report the error } // by default print on standard output private java.io.PrintStream out = System.out; // used in printType(U) for labeling type names private static String[] basic = {"class", "interface", "enum", "annotation"}, supercl = {"extends", "implements"}, iFace = {null, "extends"}; private void printType( Type type, int depth, String[] labels) { if (type == null) // stop recursion -- no supertype return; // turn the Type into a Class object Class cls = null; if (type instanceof Class ) { cls = (Class ) type; } else if (type instanceof ParameterizedType) { cls = (Class ) ((ParameterizedType)type).getRawType(); } else throw new Error("Unexpected non-class type"); // print this type for (int i = 0; i < depth; i++) out.print(" "); int kind = cls.isAnnotation() ? 3 : cls.isEnum() ? 2 : cls.isInterface() ? 1 : 0 ; out.print(labels[kind] + " "); out.print(cls.getCanonicalName()); // print generic type parameters if present TypeVariable [] params = cls.getTypeParameters(); if (params.length > 0) { out.print('<'); for(TypeVariable param : params) { out.print(param.getName()); out.print(", "); } out.println("\b\b>"); } else out.println(); // print out all interfaces this class implements Type[] interfaces = cls.getGenericInterfaces(); for (Type iface : interfaces) { printType(iface, depth + 1, cls.isInterface() ? iFace : supercl); } // recurse on the superclass printType(cls.getGenericSuperclass(), depth + 1, supercl); } // end of main } // end of clss The source is at the “/home/course/java2/code/ByTopics/AnnotationReflection/Reflection” Get type token
19
19 Java Programming II Class Inspection Run: % java TypeDesc java.util.HashMap Result: class java.util.HashMap implements java.util.Map implements java.lang.Cloneable implements java.io.Serializable extends java.util.AbstractMap implements java.util.Map extends java.lang.Object Examining the kind of Class object Ask whether have a top- level type or a nested type, and if nested, some information about which kind of nested type Find out where a type fits in the type hierachy Apply to a subset of those different kinds.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.