Is adding a method to Java annotations for backward compatibility

I have an annotation available in the library. Is it possible to add a new value to this annotation in the next version without violating those that were compiled against the previous version of the library?

For example:

// version 1
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
    String firstValue();
    String secondValue();
}

If I add a method called "String thirdValue ()", I assume that a default value will be needed, since users of the deprecated annotation will not define this property.

// version 2
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
    String firstValue();
    String secondValue();
    String thirdValue() default "third";
}

At runtime, I have code that will try to read all the values:

Class myClass = MyObject.class;
MyAnnotation annotation = myClass.getAnnotation(MyAnnotation.class);
String firstValue  = annotation.firstValue();
String secondValue = annotation.secondValue();
String thirdValue  = annotation.thirdValue();

java , . http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html "13.5.7. " , .

+4
2

:

13.5.7.

, . . , , Java. , API, . API- .

Java.

:

13.5.3.

.

, , .

, .

@Retention(RetentionPolicy.RUNTIME)
@Target (ElementType.TYPE)
@interface MyAnnotation {
    String foo ();
}

:

@FooAnnotation(foo = "Foo")
public class MyAnnotatedClass {
    public static void main (String[] args) {
        FooAnnotation annot = MyAnnotatedClass.class.getAnnotation(FooAnnotation.class);
        Method[] methods = FooAnnotation.class.getDeclaredMethods();
        System.out.println("Methods:");
        for (Method method : methods) {
            System.out.println(method.getName() + "() returns:\n");
            try {
                String value = (String) method.invoke(annot);
                System.out.println("\t" + value);
            } catch (Exception e) {
                System.out.println("\tERROR! " + e.getMessage());
            }
        }
    }
}

, :

Methods:
foo() returns:

        Foo

:

@Retention(RetentionPolicy.RUNTIME)
@Target (ElementType.TYPE)
@interface MyAnnotation {

    String foo ();
    String bar ();
}

, MyAnnotatedClass. - : MyAnnotation , , MyAnnotatedClass . , :

Methods:
bar() returns:

        ERROR! null
foo() returns:

        Foo

? ! , bar() . , , , .

, . , :

java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at example.MyAnnotatedClass.main(MyAnnotatedClass.java:16)
Caused by: java.lang.annotation.IncompleteAnnotationException: example.FooAnnotation missing element bar
        at sun.reflect.annotation.AnnotationInvocationHandler.invoke(Unknown Source)
        at com.sun.proxy.$Proxy1.bar(Unknown Source)
        ... 5 more

bar() IncompleteAnnotationException. Javadoc :

, , , ( ). , . API, .

+2

JLS 9.7, , , , , .

+1

All Articles