IntelliJ IDEA greys out some unused methods but not all

Viewed 3962

In IntelliJ IDEA 2017.2.6 I have the following Java class.

public class EinzUnregisterResponseMessageBody extends EinzMessageBody {

    private final String username, reason;

    public EinzUnregisterResponseMessageBody(String username, String reason){
        this.username = username;

        this.reason = reason;
    }

    /**
     * @return the body as JSONobject, ready to be included as "body":{this returned Object} in a message
     */
    @Override
    public JSONObject toJSON() throws JSONException {
        return new JSONObject("{\"username\":\""+this.username+"\"," +
                "\"reason\":\""+this.reason+"\"}");
    }

    public String getReason() {
        return reason;
    }

    public String getUsername() {
        return username;
    }
}

IntelliJ usually displays unused properties in light grey. In this class, it only greys out getReason(). It makes sense that it does not grey out the constructor or the fields. The method toJSON() is defined in the abstract superclass EinzMessageBody and thus has to exist, so it is correct that this is not greyed out either. getReason() is never used and thus greyed out. But why is getUsername() not greyed out? When I right-click it and select Find usages, IntelliJ reports that no usages are found.

I am aware of this question, but running Analyze>Inspect Code and Analyze>Run Inspection By Name>Unused Properties don't seem to have any effect on this. Neither does restarting the IDE.

Invalidate Caches and Restart first resets the display so that nothing is greyed out, but once it finished Indexing, the highlighting is again the same.

Here's how it is displayed in IntelliJ How it looks like for me

The superclass EinzMessageBody only specifies toJSON() and neither getReason() nor getUsername().

What is the difference between getReason() and getUsername() ?

Regarding @HonzaZidek's comment:

  • Removing the extends EinzMessageBody and the annotation @Override does not change anything.

  • Creating a completely empty project and pasting only this class and EinzMessageBody makes everything greyed out except the toJson() method. This is as expected because I am now not instantiating the class - thus the constructor being greyed out, and both getReason() and getUsername() behave the same (both greyed out).

    • This still behaves as expected when I move the classes to different subpackages, like they are in my real project setup.

    • This still behaves as expected when I instantiate the Class: The constructor stops being greyed out, getReason() and getBody() are still correctly greyed out.

I just pulled on my Laptop (as opposed to the Desktop PC) and the same behaviour happens there as well.

I searched also for any usages of getUsername() on other subclasses of EinzMessageBody and found one. Removing this one did not change the getUsername() in EinzUnregisterResponseMessageBody to be greyed out though.

This answer suggests to run Analyze>Run Inspection By Name>Unused Declaration, because IntelliJ might not check commonly used names for performance reasons. That lists both getReason() and getUsername() as unused, but the display style remains the same.

1 Answers

I'm afraid that it really is, as you suspect, the optimization built-in into IntelliJ Idea. You may report it as a bug or feature request in JetBrains's Issue Tracker - at least there would be nice having the option to turn the optimization off.

Following the existing answers https://stackoverflow.com/a/32049386/2886891 and https://stackoverflow.com/a/40870673/2886891, I am adding a reference to the IntelliJ Idea's description under Settings | Editor | Inspections | Java | Declaration Redundancy | Unused declaration:

Some unused members might not be reported during in-editor highlighting. Due to performance reasons, a non-private member is checked only when its name rarely occurs in the project.

enter image description here

Related