Статические публичные методы и нестатические методы по умолчанию в интерфейсах
Просматривая исходный код интерфейса 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
,