Deprecate class inheritance only
Asked Answered
M

5

9

I would like to deprecate only the extension of a given class, not all the methods and fields contained within a class, using the @Deprecated annotation.

That is, a warning will occur if you extend a given class - but references to methods or fields will not trigger a warning. There are already several classes that extend this class, and I want to have the deprecation warnings target these clients - I can't break them yet (but they can be recompiled - ABI compatibility not needed).

Is it possible in Java 1.6 (JDT compiler)?

Microbicide answered 14/2, 2011 at 19:24 Comment(2)
As an update given the answers so far - I need to allow classes to continue to extend the class, as I can't remove the dependency yet - but I want them to get deprecation warnings on doing so.Microbicide
Thanks for the answers. In the end, none of the solutions below were full adequate (use of final is a non-starter, because I want to warn, not to break), so I settled for deprecating the protected constructors that subclasses must use, which had a similar effect (one deprecation warning per extension).Microbicide
E
6

Two considerations

1) The class may already be extended, so don't mark it final or you could break backwards compatibility.

2) You don't want the class extended, so it should be marked final.

I think what you should do is extend the old class with a new class, mark the old class deprecated, and declare the new class final. In the new class, you can add the @SuppressWarning tag to quiet the deprecated message, then you should sitll get a clean compile.

Code using the old class will get a @Deprecated Warning, but will still compile.. Code using the new class will compile cleanly. Kind of a "strong suggestion" to your users instead of a backward compatible break, and pretty easy for them to fix since the API is 100% compatible.

Echo answered 14/2, 2011 at 19:38 Comment(1)
Marking this one the answer, as it is most along the times of what I needed - a way to warn consumers about extending the class, without actually breaking them or warning on each method invocation.Microbicide
V
4

I doubt that this is possible using the @Deprecated annotation.

If you have control over the sources you could however do the following:

  1. Rename the current class SomeClass to SomeClassSuper
  2. Create a new class named SomeClass and let it extend SomeClassSuper.
  3. Make SomeClass final (which prevents clients from extending it).

That is, go from

class SomeClass {
    // ...
}

class SubClass extends SomeClass {
    // ...
}

to

class SomeClassSuper {
    // ...
}

class SubClass extends SomeClassSuper {
    // ...
}

final class SomeClass extends SomeClassSuper {
    // ...
}
Verrazano answered 14/2, 2011 at 19:27 Comment(0)
E
1

No, no way. You can make the class final, but thus you'll break existing extensions.

Perhaps it is possible by developing a custom processor for the APT. But it will not be enforced in the general case.

Earleanearleen answered 14/2, 2011 at 19:29 Comment(0)
E
1

If it fits your design you could perhaps make needed functionality (e.g. constructors that descendants need to access) private, and provide a protected+deprecated constructor which extensions would need to use.

Encomiast answered 14/2, 2011 at 19:33 Comment(0)
S
0

The @Deprecated annotation does not support this, you should mark your class final instead. While this causes a compiler error it is more logical, either it is safe to extend your class or it is an error to do it.

Suffix answered 14/2, 2011 at 19:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.