Annotations Over Naming Conventions

Many libraries, frameworks and systems manipulate Java objects and classes through reflection. Examples include ObjectRelationalMapping tools that persist objects to databases, XML binding tools that map XML documents to and from Java objects, serialisation libraries that write and read objects to and from streams, test frameworks that load and run tests written as Java classes.

These reflective systems work at the MetaLevel, manipulating Java classes, methods and fields and untyped objects. From this meta-level representation they must infer information to guide their operation. An object relational mapper must determine how to map the features of an object to database tables and columns. An XML serialiser must determine how features of an object are represented as XML elements and attributes. A serialiser must determine how features of an object are represented as a stream of bits. A test framework must determine which classes contain tests and which methods of those classes are tests and which are called from the tests and can't be run directly.

Prior to Java 5, reflective code had to infer this information from coding conventions, such as TagInterfaces, the inheritance hierarchy and NamingConventions, or used configuration files.

Naming conventions can restrict the vocabulary used by the programmer too much. TagInterfaces abuse a language feature and so make it harder to understand the code. Forcing classes to have a specific base class makes it harder to use existing code with the reflective tool or to refactor inheritance hierarchies to remove duplication.

Java 5 introduced a new language feature, annotations, borrowed from C#. An annotation is an explicit piece of MetaData attached to a class, method, field or variable. A language element can be given as many annotations as necessary. Annotations are interpreted by a reflective tool that can understand them. This lets the programmer integrate their class with different reflective tools without needing to follow any prescribed coding conventions or design styles.

However, the annotation syntax is ugly and many annotations make the code cluttered and hard to read.

When should you use annotations instead of naming conventions?

... to be done...


Rewritten above.

Prior to Java 1.5 TagInterfaces are used to provide MetaData about classes. What about methods? Unfortunately, whilst reflection allows introspection about the class hierarchy - and hence implemented TagInterfaces, there's no such similar mechanism that can be used for methods. What can be known about a method includes its name; hence the MetaData is intertwined with the method name. For example JavaBeans should use methods that begin with 'get' and 'set' to allow BeanBoxes to set and get properties for a VisualClass?.

Annotations provide a more flexible mechanism. One possibility to replace the get/set convention above would be to have two annotations, @BeanGetter and @BeanSetter. Or perhaps just a @Bean annotation parameterised with an enumeration: @Bean(MethodType.GETTER), @Bean(MethodType.SETTER). A BeanBox would then use the annotation information associated with the methods rather than the name.

But, annotations are ugly and clutter the code compared to using a well chosen SystemOfNames that expresses the same information.

Please add to NamingConventionsOverAnnotations?! I prefer annotations so I've avoided doing the page myself.

They are both patterns, so are applicable in different contexts. The pages should compare and contrasts those contexts, not document personal preferences.

Indeed, which is why I've avoided interjecting any personal bias.

Sorry, what I meant was that there are situations where annotations are more useful than naming conventions and other situations where naming conventions are more useful than annotations. Personal bias doesn't come into it, so there's no reason why you can't write the page yourself.


Actually, Java Beans do not have to use "get" and "set" prefixes. The mapping of named properties to getter and setter methods is defined by the bean's BeanInfo class and the "get" and "set" prefixes are used when the Beans API must FallBackOnReflection to generate a BeanInfo for classes without explicitly defined metadata.

See:

A better example might be JUnit 4 or TestNG that use @Test annotations to identify methods to run as tests, while JUnit 3 looks for methods that start with "test".

Probably but I wanted to use something different to AnnotationsOverTagInterfaces, but thanks for the clarification. Any other good JavaNamingConventions examples?


See Also: NamingConventionsOverAnnotations? AnnotationsOverTagInterfaces

SeptemberZeroSix

Category: JavaIdioms


EditText of this page (last edited September 28, 2006) or FindPage with title or text search