Статические публичные методы и нестатические методы по умолчанию в интерфейсах

Просматривая исходный код интерфейса java.util.Collections для Java 1.8, я заметил это,

default boolean removeIf(Predicate<? super E> filter) 
{
 ....
}

Так, начиная с 1.8, java позволяет методам в интерфейсах определять тела. Однако есть несколько смысловых особенностей; если метод публичный, мне нужно явно указать его как статический, это понятно, но почему это не применяется по умолчанию? на самом деле указание статического по умолчанию дает ошибку. Какой цели это служит?

РЕДАКТИРОВАТЬ: видя количество отрицательных голосов, я бы посоветовал вам сначала попробовать это, прежде чем делать выводы в неверии

2 ответа

Я попытался скомпилировать следующий тестовый интерфейс:

public interface TestInterface {
                    void m();
           abstract void am();
           default  void dm() { }
           static   void sm() { }
    public          void pm();
    public abstract void pam(); 
    public default  void pdm() { }
    public static   void psm() { }
}

используя JDK, я случайно лежал, а именно: 8, 8u5, 8u11, 8u25, 8u40 и сборка jdk9-dev, сделанная пару дней назад. Он успешно скомпилирован на всех этих версиях.

Как уже отмечалось, все методы в интерфейсе общедоступны, независимо от того, public указан. Кроме того, метод может быть абстрактным, заданным по умолчанию или статическим, а метод является абстрактным, если ни один из них не указан. ( JLS 9.4) Наконец, объявленные методы default или же static должен иметь блок { ... } для тела, тогда как абстрактные методы (объявленные или нет) должны иметь точку с запятой ; как тело. ( JLS 9.4.3)

если метод публичный, мне нужно явно указать его как статический... но почему это не применяется по умолчанию? (из комментария) ключевое слово static должно быть там, если оно общедоступно.

Я не вижу этого Все методы интерфейса являются открытыми, независимо от того, были ли они явно объявлены как таковые. Это ортогонально тому, что метод является статическим или используется по умолчанию.

на самом деле указание статического по умолчанию дает ошибку.

Да, метод может быть статическим или по умолчанию, но не обоими.

Я получаю сообщение об ошибке "интерфейс абстрактных методов не может иметь тела"

Если вы получаете эту ошибку, вы должны указать блок { ... } как тело для абстрактного метода, независимо от того, явно ли метод объявлен как абстрактный.

(JDK 9 недавно добавил поддержку частных методов в интерфейсах.)

Так, начиная с 1.8, Java позволяет методам в интерфейсах определять тела

Нет, это не так. Вы можете - должны на самом деле - определить тело для методов, помеченных как default или же static, Но вы не можете определить тело для абстрактного метода, что вы и пытались сделать.

Метод может быть abstract, default или же static, Если ключевое слово не используется, то это abstract, abstract означает не иметь реализации. default означает наличие реализации, которая используется, если класс не предоставляет свою собственную. Метод помечен как static не наследуется классу.

Так что все они разные, служат разным целям и не могут быть смешаны. Метод по умолчанию должен быть унаследован, поэтому он не может быть static,

Другие вопросы по тегам