Asdfasf

Sunday, August 24, 2014

EJ-35 Prefer Annotations to naming patterns

Ref: Effective Java by Joshua Bloch

Prior to release 1.5, it was a common to use naming pattern to indicate that some program elements demanded special treatment by a tool or a framework. For example, the JUnit testing framework originally required its users to designate test methods by beginning theri names with the characters test. This technique works but
  • it is open to typograhapicals error.
  • There is no way to associate parameter values with program elements (such as marking a test method with exception expectation)

Annotations solve all of these problems. Here is a sample annotation type, named Test:

// Marker annotation type declaration
import java.lang.annotation.*;
/**
* Indicates that the annotated method is a test method.
* Use only on parameterless static methods.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
}


Annotations have no direct effect on the semantics of class, they serve only to provide information for use by interested programes, enabling it for special treatment by tools such as this simple test runner by checking isAnnotationPresent on method, see line 10.

// Program to process marker annotations
import java.lang.reflect.*;
public class RunTests {
public static void main(String[] args) throws Exception {
int tests = 0;
int passed = 0;
Class testClass = Class.forName(args[0]);
for (Method m : testClass.getDeclaredMethods()) {
if (m.isAnnotationPresent(Test.class)) {
tests++;
try {
m.invoke(null);
passed++;
} catch (InvocationTargetException wrappedExc) {
Throwable exc = wrappedExc.getCause();
System.out.println(m + " failed: " + exc);
} catch (Exception exc) {
System.out.println("INVALID @Test: " + m);
}
}
}
System.out.printf("Passed: %d, Failed: %d%n",
passed, tests - passed);
}
}
view raw RunTests.java hosted with ❤ by GitHub



 

No comments: