views:

1042

answers:

3

Consider the following simplified interface inheritence hierarchy:

// Starting point:
public interface Base {
    void Foo();
}

public interface Derived extends Base {
}

It is intended to move the Foo method from the Base interface to the Derived interface:

// Desired end-point:
public interface Base {
}

public interface Derived extends Base {
    void Foo();
}

In order to phase in this breaking change, it is desired to retain backwards compatibility of the Base interface for some time.

This can be achieved by marking the method on the Base interface as @Deprecated:

// Intermediate state:
public interface Base {
    /**
     * @deprecated This method is deprecated as of release X. Derived.Foo should be used instead.
     */
    @Deprecated void Foo();
}

public interface Derived extends Base {
    void Foo(); 
}

When I compile this code I receive a compiler warning for Derived:

[deprecation] Foo() in interface Base has been deprecated

Oddly, if I remove the @deprecated from the documentation in Base (but leave the @Deprecated) this warning disappears.

Is it correct that I get this warning, and if so, how can I work around this?


The warning seems to communicate that Derived.Foo is "using" Base.Foo (which is deprecated). But the only capacity in which Derived.Foo is "using" the deprecated Base.Foo is to override it. That seems to say that you are not allowed to override deprecated interface methods in derived methods.

If this is the case, should I then decorate Derived with @SuppressWarnings("deprecation") to suppress the warning?

+1  A: 

if I understand correctly, you need a @SuppressWarnings("deprecation") at the beginning of your classes that implement the deprecated interface/function. Or am I way off base here?

MattC
That sounds reasonable, however the problem here is that there _are_ no implementing classes. Just the two interfaces. The warning seems to communicate that `Derived.Foo` is "using" `Base.Foo` (which is deprecated). But the only capacity in which `Derived.Foo` is "using" the deprecated `Base.Foo` is to override it. That seems to say that you are not allowed to override deprecated interface methods in derived methods. Is this reasonable?
Daniel Fortunov
I don't know about "not allowed", but since you are in fact overriding a deprecated function it seems reasonable to me that it would complain about it. Is there any way to decouple them and have them be two completely separate interfaces or does Derived have to extend for other functionality?
MattC
+1  A: 

I believe your requirement is valid, I have no doubt that overriding the deprecated method is the correct way to go.

I believe the difference between @deprecated and @Deprecated is mainly historical. @Deprecated is the official way in java 5, but is new, so we are expected to double it with @deprecated.

Also note that, sadly enough, @Deprecated doesn't let you specify information .. while information is usually needed, for example to tell what should be used as a replacement, or when the deprecated method is expected to be completely removed.

Not knowing more, and knowing the problem will disappear as soon as you effectively remove the super method, I would use the @SuppressWarnings("deprecation"), possibly with a comment for your successors to understand ... (and another comment on the super method to tell them to remove all that when deleting the method). ;-)

KLE
A: 

There is no way to accomplish what you want.

Deprecation is a relatively simply mechanism and does not support this use case.

The way that deprecation works is that anything that references a deprecated method or field generates a warning.

The only exception is if the code using the deprecated method/field is deprecated itself.

Noel Grandin
And that's the correct reaction (instead of suppressing the warning), because you rely in your derived method on deprecated APIs.
Mnementh
The point of introducing the method on `Derived` is to migrate the method from `Base` to `Derived`, hence I want to deprecate the method on `Base` and provide documentation that says "use this method on `Derived`". I doesn't make sense to deprecate the (newly added) method on `Derived` in this scenario.
Daniel Fortunov