Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deprecations On Overriding Method

I found something weird in Eclipse IDE. Let's say I have the following classes:

public class Super {
    @Deprecated
    public void doNotUseThisMethod() {
        // do magic
    }
}

public class Sub extends Super{
    @Override
    public void doNotUseThisMethod() {
        // why is this not deprecated?
    }
}

Surely overriding a deprecated method should result in a warning (because the same reason for not using it applies). Still in brand new workspaces for Eclipse Luna and Mars the above code does not yield a warning at all. And I can't find any way to enable it either.

I found this bug for interfaces (I get that if Super was an interface, there should be no warning) which implies that there was a warning once upon a time.

So what happened? Is there any reason overriding a deprecated method should not result in a warning? Can I do something to enable this functionality again?

like image 614
Steffi S. Avatar asked Apr 25 '16 11:04

Steffi S.


People also ask

What is the concept of overriding method?

Method overriding, in object-oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes.

Can we override deprecated methods in Java?

java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details. Use the javac -Xlint:deprecation option to see what API is deprecated. Here is an example of a removal warning.

What happens when you override a method?

Instance Methods The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides.


2 Answers

The JLS is quite clear on this point (as it is on most points).

A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.

A Java compiler must produce a deprecation warning when a type, method, field, or constructor whose declaration is annotated with @Deprecated is used (overridden, invoked, or referenced by name) in a construct which is explicitly or implicitly declared, unless:

  • The use is within an entity that is itself annotated with the annotation @Deprecated; or

  • The use is within an entity that is annotated to suppress the warning with the annotation @SuppressWarnings("deprecation"); or

  • The use and declaration are both within the same outermost class.

(https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.4.6)

To be fully compliant with the JLS, Eclipse must mark your doNotUseThisMethod() with a warning. And it seems that it used to do that, a long time ago, but in 2003 bug 48335 came along and that warning became subject to a preference. The default, as noted in the bug comments, is "disabled". (The default should be "enabled" to be even remotely compliant with the JLS. Feel free to file a bug to get it changed.) I haven't done an exhaustive search, but since you are seeing behavior consistent with that, I'm going to go out on a limb and say that this is how it has remained ever since.

Since it's a preference, you can change it. Just go to "Window -> Preferences", then select "Java -> Compiler -> Errors/Warnings". Scroll down to "Deprecated and restricted API" and check the box next to "Signal overriding or implementing deprecated method". There's a dropdown to the right and slightly above where you can choose "Error", "Warning" or "Ignore". Select the one you prefer.

That setting affects only your local IDE.

To get your entire team using that setting, you need to set Project Specific Settings. On that same preferences screen, in the upper right there's a link to "Configure Project Specific Settings". Click it, select the project for which you want to set the preferences, and do the same thing described above. This will create a file named "org.eclipse.jdt.core.prefs" in your project's ".settings" folder. (You can't see them in Package Explorer. You'll need to look at them in the Navigator view.) Once created, you can then add them to your source control and they'll apply to everyone on your team working on that project.

Yes, you have to do that for every project.

like image 121
Erick G. Hagstrom Avatar answered Nov 06 '22 09:11

Erick G. Hagstrom


Actually the behaviour seeems the right one for me: when you override a method is a symbol you implement a new code for it.


To avoid errors, if you use a deprecated super method, eclipse will raise a warning:

class Sub extends Super{
    @Override
    public void doNotUseThisMethod() { // <---------------*
        super.doNotUseThisMethod();   // deprecated! <----*
    }
}

But if you override a deprecated method functionallity without using the deprecated super.method() then new method is not deprecated by definition, because you implemented it without using the old one.

public class Sub extends Super{
    @Override
    public void doNotUseThisMethod() {
        // new logic + not using super.method() = not a deprecated method!!
    }
}

If the one that overrides the deprecated one, shouldn't be used, must be also annotated as deprecated as follows:

public class Super {    
    @Deprecated
    public void doNotUseThisMethod() {
        // do magic
    }
}

public class Sub extends Super{
    @Override
    @Deprecated  // <---------------------------*
    public void doNotUseThisMethod() { //       |
        // this is deprecated also!!!! // <-----*
    }
}

SIDENOTE: Another question will be if the name of your method can cause confusion.


But doesn't @Deprecate also mean "we're going to delete this method soon", which will break the code of the subclass thanks to the @Override annotation? (That's exactly why I need the warning - to prevent other developers from overriding a method I'm going to delete. But as it is they won't even get a warning.) – Steffi S.

Actually It could happen developers delete the method, but deprecation is more about not using the code in some method because is old, then developers make a NEW one, with NEW name and leave deprecated one as legacy.

But... What would happen in the case this method is deleted?

First of all, this would mean a change of Java (or framework, or utils) version, this should be done carefully, deprecated methods won't be your only problem.

In the case you choose major version and some deprecated methods are deleted, you won't have much problem... Why? Your IDE will clearly mark this methods with an error, and you just need to delete the @Override annotation, having your logic safe in your overriden method.

like image 23
Jordi Castilla Avatar answered Nov 06 '22 08:11

Jordi Castilla