Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deprecate class inheritance only

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)?

like image 392
BeeOnRope Avatar asked Feb 14 '11 19:02

BeeOnRope


People also ask

Can we deprecate a class in Java?

Starting with J2SE 5.0, you deprecate a class, method, or field by using the @Deprecated annotation. Additionally, you can use the @deprecated Javadoc tag tell developers what to use instead. Using the annotation causes the Java compiler to generate warnings when the deprecated class, method, or field is used.

Why deprecated method should not be used?

A deprecated class or method is like that. It is no longer important. It is so unimportant, in fact, that you should no longer use it, since it has been superseded and may cease to exist in the future.

What is a deprecated class?

Similarly, when a class or method is deprecated, it means that the class or method is no longer considered important. It is so unimportant, in fact, that it should no longer be used at all, as it might well cease to exist in the future. The need for deprecation comes about because as a class evolves, its API changes.

Is it bad to use deprecated methods in Java?

Never use deprecated fields, methods, or classes in new code. Java provides an @deprecated annotation to indicate the deprecation of specific fields, methods, and classes. For example, many methods of java. util.


3 Answers

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.

like image 163
Zak Avatar answered Oct 16 '22 22:10

Zak


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 {
    // ...
}
like image 24
aioobe Avatar answered Oct 16 '22 21:10

aioobe


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.

like image 43
Bozho Avatar answered Oct 16 '22 22:10

Bozho