Duplicate :
|
A DESCRIPTION OF THE REQUEST : It is common good practice to code defensively so that, for example: when returning a state of an object which is a collection, you wrap that collection in an "unmodifiable" layer. In user-developed code, it is frequently the case that user defined Objects should sometimes be passed around in a "look-but-don't-touch" form. I believe that the Annotation framework introduced in JDK5 allows us to provide "native" support in Java for this programming model. I would declare 3 Annotations in the java.lang package ---- Mutator Annotation ------------ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.METHOD) public @interface Mutator { } ---- End Mutator ----- The mutator annotation would declare that an operation (method) on an Object was state-changing. ---- Immutable annotation -------- @Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface Immutable {} ----- End class ----- The immutable annotation would indicate to the compiler that the parameter/field/local variable was Immutable. That is, a compiler error/warning would result if one were to call a method annotated with @Mutator on such a parameter/field/variable. ---- ReturnsImmutable Annotation ---- @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.SOURCE) public @interface ReturnsImmutable {} ---- Ends ReturnsImmutable ---- The ReturnsImmutable annotation would declare whether the object returned by either a Constructor (or more likely a method) should be treated as Immutable. RULES: 1). You cannot assign a non-Immutable field/variable/parameter to a Immutable field/variable/parameter. For example, suppose myMethod has a parameter myParam which is un-annotated @Immutable Object myObject = new SomeObject(); Object hisObject = myObject; Would result in an error/warning, as would myMethod(myObject); //as the signature of myMethod did not declare its parameter as @Immutable 2). You cannot assign a non-Immutable variable/field/parameter to the result of a method marked @ReturnsImmutable. Suppose myMethod() is marked as such: Object myObject = myMethod(); Would result in an error/warning 3). The annotations @ReturnsImmutable and @Mutator should work similarly to thrown Exceptions in terms of method overriding. That is, a superclass or interface declaring a method as @Mutator should not mean that sub-classes/interfaces need override the method as a @Mutator. 4). The annotations @ReturnsImmutable and @Mutator should work similarly to thrown Exceptions in terms of implementations inheriting identical method signatures from one or more interfaces. That is, the sub-classes must annotate only the intersection of the super-interface annotations JUSTIFICATION : This enhancement is necessary from the perspective of allowing the developer to inform the compiler of his/her intentions. The Immutability/mutability of Objects is a fundamental part of application development and the more the compiler can help enforce developer intentions, the more robust Java would be as a language to support application-development. The Annotations would reduce the need for developers to split out interfaces into immutable and mutable (ie. the mutable interface extending the immutable interface adding the mutators). Although I could develop my own annotation-processing framework to achieve these goals, I think that the feature would be beneficial to the Java language and would also require expertise in understanding language compilation which I may lack! EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - An example with returning unmodifiable Lists etc. I would ensure that the add, addAll, clear, remove and removeAll methods from the List interface were all to be annotated with @Mutator. Collections.java @ReturnsImmutable public static List unmodifiableList(List list) { return list; } ...and usage @Immutable List list = Collections.unmodifiableList(myList); ...or more simply @Immutable List list = myList;