Private interface methods are supported

2019-01-27 03:38发布

问题:

Private interface methods are supported by Java 9.

This support allows non-abstract methods of an interface to share code between them. Private methods can be static or instance.

Can private methods of an interface be abstract or default?

May I ask for an example where "private static interface methods" are useful in terms of code?

回答1:

No, the private methods in the interfaces are supposedly designed for clubbing in a piece of code that is internal to the interface implementation. Since these pertain to the implementation(consist of a body) and not the declaration it can neither be default and nor abstract when defined.

A private method is a static method or a non-default instance method that's declared with the private keyword. You cannot declare a default method to also be private because default methods are intended to be callable from the classes that implement their declaring interfaces.


The private static methods are useful in abstracting a common piece of code from static methods of an interface while defining its implementation.

Example of a private static method in an interface could be as follows. Consider an object, Question.java on StackOverflow defined as:

class Question {
    int votes;
    long created;
}

and an interface that proposes the sort by functionality as seen in the listed questions on StackOverflowTag :

public interface StackOverflowTag {

    static List<Question> sortByNewest(List<Question> questions) {
        return sortBy("NEWEST", questions);
    }

    static List<Question> sortByVotes(List<Question> questions) {
        return sortBy("VOTE", questions);
    }

    //... other sortBy methods

    private static List<Question> sortBy(String sortByType, List<Question> questions) {
        if (sortByType.equals("VOTE")) {
            // sort by votes
        }
        if (sortByType.equals("NEWEST")) {
            // sort using the created timestamp
        }
        return questions;
    }
}

Here the private static method sortBy of the interface internally implements the sorting based on the sortOrderType sharing the implementation with two public static methods of the interface which can be further consumed by a StackOverflowTagConsumer can simply access these interface static methods as :

public class StackOverFlowTagConsumer {

    public static void main(String[] args) {
        List<Question> currentQuestions = new ArrayList<>();

        // if some action to sort by votes
        displaySortedByVotes(currentQuestions);

        // if another action to sort by newest
        displaySortedByNewest(currentQuestions);
    }

    private static void displaySortedByVotes(List<Question> currentQuestions) {
        System.out.println(StackOverflowTag.sortByNewest(currentQuestions));
    }

    private static void displaySortedByNewest(List<Question> currentQuestions) {
        System.out.println(StackOverflowTag.sortByNewest(currentQuestions));
    }
}


回答2:

The default keyword for interface methods exist, because for interface methods, abstract is implicitly assumed if no other modifier contradicts it. Before Java 8, this applied to all interface methods, which were always considered abstract.

Since the presence of either, static or private, already implies that it cannot be abstract (which applies to ordinary classes as well), there is no need to add a default modifier and consequently, Java rules out this combination. And there is no point in asking for this combination either, as default merely implies that the method is not abstract, technically, so adding it to a method which is already not abstract wouldn’t change anything.

On the other hand, since the only methods needing a default keyword for declaring that they are not abstract, are public instance methods, the default keyword only applies to overridable methods, which conveniently matches the literal meaning of the word “default”.

private methods are useful to provide common operations for the public non-abstract methods of an interface when these common operations are not supposed to be called from the outside of the interface directly, much like private methods in ordinary classes, further, they exist in Java 8 already on the byte code level, as default and static methods may contain lambda expressions which are compiled into synthetic private methods, so there was no technical reason to deny that feature to the Java programming language.



回答3:

No, these three combinations are mutually exclusive. Interface methods cannot be at the same time:

  • Default and abstract (because default means the opposite of abstract)
  • Default and private (because you cannot override a private method)
  • Abstract and private (because you cannot override a private method)