Declarative Programming in Java
2009-07-29 22:49
344 查看
public static interface PublicMethod
extends Annotation
{
}
public static interface PrivateMethod
extends Annotation
{
}
上面是Palm里面用到的Annotation,特转载下面一篇文章(http://www.ericdlarson.com/misc/chrome_command_line_flags.html)。
04/21/2004 What makes EJB components special is the declarative programming model through which we can specify the services such as security, persistence, transaction etc., that the container should provide. An EJB only implements the business logic; the services are associated through a deployment descriptor, which essentially acts as metadata for the EJB. At runtime, the container uses the metadata specified in the deployment descriptor to provide the services. The deployment descriptor is an XML file, not part of the Java classes that make up the EJBs. Is there a standard way to annotate the Java classes that make up the EJBs so that a developer can look at the class definition, together with annotations, and know everything about that class? It would be even better if the remote, home interfaces and the deployment descriptor could be automatically generated by a tool using the annotations. Better yet, can we provide the same kind of declarative services for a simple Java object? If so, how? This article examines how JSR-175: A Metadata Facility for the Java Programming Language will help us in finding answers to these questions and more.
Approaches to Programming There are two approaches to programming called imperative programming and declarative programming. Imperative programming gives a list of instructions to execute in a particular order -- Java program that counts the number of words in a text file is an example of the imperative approach. Declarative programming describes a set of conditions, and lets the system figure out how to fulfill them. The SQL statement
Annotations The Tiger release of Java (JDK 1.5) adds a new language construct called annotation (proposed by JSR-175). Annotation is a generic mechanism for associating metadata (declarative information) with program elements such as classes, methods, fields, parameters, local variables, and packages. The compiler can store the metadata in the class files. Later, the VM or other programs can look for the metadata to determine how to interact with the program elements or change their behavior.
Declaring an Annotation Declaring an annotation is very simple -- it takes the form of an interface declaration with an
The
Using an Annotation
Here is an example that shows how to use the
An annotation is applied to the code element by placing an annotation statement (
Accessing Annotations at Runtime
Once annotations have been associated with program elements, we can use reflection to query their existence and get the values. The main reflection methods to query annotations are in a new interface:
Methods available in the
Returns
Returns this element's annotation for the specified type if such an annotation is present, else null.
Returns all annotations present on this element. (Returns an array of length zero if this element has no annotations.)
Returns all annotations that are directly present on this element. Unlike the other methods in this interface, this method ignores inherited annotations. (Returns an array of length zero if no annotations are directly present on this element.)
You may notice that the
Here is the list of classes that implement the
Next, I'll show you an example that illustrates how to access annotations at runtime.
The
Here is how the
In our
When run with the command
Pages: 1, 2, 3
Next Page
extends Annotation
{
}
public static interface PrivateMethod
extends Annotation
{
}
上面是Palm里面用到的Annotation,特转载下面一篇文章(http://www.ericdlarson.com/misc/chrome_command_line_flags.html)。
Declarative Programming in Java
by Narayanan Jayaratchagan04/21/2004 What makes EJB components special is the declarative programming model through which we can specify the services such as security, persistence, transaction etc., that the container should provide. An EJB only implements the business logic; the services are associated through a deployment descriptor, which essentially acts as metadata for the EJB. At runtime, the container uses the metadata specified in the deployment descriptor to provide the services. The deployment descriptor is an XML file, not part of the Java classes that make up the EJBs. Is there a standard way to annotate the Java classes that make up the EJBs so that a developer can look at the class definition, together with annotations, and know everything about that class? It would be even better if the remote, home interfaces and the deployment descriptor could be automatically generated by a tool using the annotations. Better yet, can we provide the same kind of declarative services for a simple Java object? If so, how? This article examines how JSR-175: A Metadata Facility for the Java Programming Language will help us in finding answers to these questions and more.
Approaches to Programming There are two approaches to programming called imperative programming and declarative programming. Imperative programming gives a list of instructions to execute in a particular order -- Java program that counts the number of words in a text file is an example of the imperative approach. Declarative programming describes a set of conditions, and lets the system figure out how to fulfill them. The SQL statement
SELECT COUNT(*) FROM XYZis an example for the declarative approach. In other words, "specifying how" describes imperative programming and "specifying what is to be done, not how" describes declarative programming.
Annotations The Tiger release of Java (JDK 1.5) adds a new language construct called annotation (proposed by JSR-175). Annotation is a generic mechanism for associating metadata (declarative information) with program elements such as classes, methods, fields, parameters, local variables, and packages. The compiler can store the metadata in the class files. Later, the VM or other programs can look for the metadata to determine how to interact with the program elements or change their behavior.
Declaring an Annotation Declaring an annotation is very simple -- it takes the form of an interface declaration with an
@preceding it and optionally marked with meta-annotations, as shown below:
package njunit.annotation; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface UnitTest { String value(); }
The
Retentionmeta-annotation declares that the
@UnitTestannotation should be stored in the class file and retained by the VM so it may be read reflectively. The
Targetmeta-annotation declares that the
@UnitTestannotation can be used to annotate methods in a Java class.
@interfacedeclares the
@UnitTestannotation with one member called
value, which returns a
String.
Using an Annotation
Here is an example that shows how to use the
@UnitTestannotation declared in the previous section:
import njunit.annotation.*; public class Example { @UnitTest(value="Test 1. This test will pass.") public void pass() { assert 10 > 5; } @UnitTest("Test 2. This test will fail.") public void fail() { assert 10 < 5; } }
An annotation is applied to the code element by placing an annotation statement (
@AnnotationType(...)) before the program element. Annotation values take the form
"name=value"; for example,
@UnitTest(value="some text"). Single-member annotations with a member named
valueare treated specially and can use the shorthand
@UnitTest("some text"). In the example, the
@UnitTestannotation is associated with the
passand
failmethods.
Accessing Annotations at Runtime
Once annotations have been associated with program elements, we can use reflection to query their existence and get the values. The main reflection methods to query annotations are in a new interface:
java.lang.reflect.AnnotatedElement.
Methods available in the
AnnotatedElementinterface are:
boolean isAnnotationPresent(Class extends Annotation> annotationType)
Returns
trueif an annotation for the specified type is present on this element, else
false. This method is designed primarily for convenient access to marker annotations.
T getAnnotation(Class annotationType)
Returns this element's annotation for the specified type if such an annotation is present, else null.
Annotation[] getAnnotations()
Returns all annotations present on this element. (Returns an array of length zero if this element has no annotations.)
Annotation[] getDeclaredAnnotations()
Returns all annotations that are directly present on this element. Unlike the other methods in this interface, this method ignores inherited annotations. (Returns an array of length zero if no annotations are directly present on this element.)
You may notice that the
isAnnotationPresentand
getAnnotationmethods are defined using generics, another new feature available in JDK 1.5.
Here is the list of classes that implement the
AnnotatedElementinterface:
java.lang.reflect.AccessibleObject
java.lang.Class
java.lang.reflect.Constructor
java.lang.reflect.Field
java.lang.reflect.Method
java.lang.Package
Next, I'll show you an example that illustrates how to access annotations at runtime.
package njunit; import java.lang.reflect.*; import njunit.annotation.*; public class TestRunner{ static void executeUnitTests(String className) { try { Object testObject = Class.forName(className).newInstance(); Method [] methods = testObject.getClass().getDeclaredMethods(); for(Method amethod : methods) { UnitTest utAnnotation = amethod.getAnnotation(UnitTest.class); if(utAnnotation!=null) { System.out.print(utAnnotation.value() + " : " ); String result = invoke(amethod, testObject); System.out.println(result); } } }catch(Exception x) { x.printStackTrace(); } } static String invoke(Method m, Object o) { String result = "passed"; try{ m.invoke(o,null); } catch(Exception x) { result = "failed"; } return result; } public static void main(String [] args) { executeUnitTests(args[0]); } }
The
TestRunneruses the
@UnitTestannotation to determine whether a method is a unit test or not, invoke the method if it is marked with the
@UnitTestannotation, and report the success or failure.
Here is how the
TestRunnerexecutes the unit test. Given a Java class, the
TestRunnerfirst obtains the list of all declared methods using reflection. Then it queries each method using the enhanced
forconstruct and the
getAnnotationmethod available in JDK 1.5 to find out whether it is marked as a
@UnitTest. If it is marked, then it invokes the method and reports the success or failure. A test is considered failed if there is any exception when executing the test, and is considered passed otherwise.
In our
Exampleclass, the
passmethod will succeed when invoked, but the
failmethod will throw an
AssertionError, which is propagated to the
TestRunner.invokemethod as
InvocationTargetException.
When run with the command
java -ea njunit.TestRunnerExample, the output looks like the following:
Test 1. This test will pass. : passed Test 2. This test will fail. : failed
Pages: 1, 2, 3
Next Page
相关文章推荐
- 简要介绍JAVA8中的函数式编程;Brief Introduction to Functional Programming in Java 8
- Java Socket Programming in Client/Server Applications - 转自 http://www.developer.com/
- 10 Exception handling Best Practices in Java Programming
- [Introduction to programming in Java 笔记] 1.3.9 Factoring integers 素因子分解
- Concurrent and Real-Time Programming in Java
- [Concurrent Programming in Java]CookieJar Problem
- Java Comparators in a More Declarative Way
- 《Concurrent Programming in Java: Design Principles and Patterns》Second Edition
- Java2核心技术第七版的学习笔记(三) Fundamental Programming Structures in Java(Java语言的基础)(二)
- 转:Password Masking in the Java Programming Language
- Scala学习整理[第二十七-二十九章 模块化编程和Java]<Programming In Scala>
- Programming Methodology in Java 笔记
- [Java 多线程] Concurrent Programming in Java BOOK
- Mastering AspectJ: Aspect-Oriented Programming in Java
- Udp socket programming in Java
- Multi-threading programming in Java
- LdapTemplate: LDAP Programming in Java Made Simple
- parallel programming in java introduce
- Chapter 3. Fundamental Programming Structures in Java
- Java2核心技术第七版的学习笔记(三) Fundamental Programming Structures in Java(Java语言的基础)(一)