Почему все поля в интерфейсе неявно статичны и окончательны? - PullRequest
91 голосов
/ 03 октября 2009

Я просто пытаюсь понять, почему все поля, определенные в интерфейсе, неявно static и final. Идея сохранения полей static имеет смысл для меня, поскольку у вас не может быть объектов интерфейса, но почему они final (неявно)?

Кто-нибудь знает, почему дизайнеры Java пошли на создание полей в интерфейсе static и final?

Ответы [ 7 ]

121 голосов
/ 03 октября 2009

Интерфейс не может иметь поведение или состояние, поскольку он предназначен для указания только контракта взаимодействия, без подробностей реализации. Поведение не применяется, если не разрешены тела методов / конструкторов или статические / экземпляры, инициализирующие блоки. Никакое состояние не обеспечивается только разрешением статических полей final. Поэтому у Class может быть состояние (статическое состояние), но состояние экземпляра не определяется интерфейсом.

Кстати: константа в Java определяется статическим конечным полем (и по соглашению имя использует UPPER_CASE_AND_UNDERSCORES).

25 голосов
/ 11 марта 2012

ПРИЧИНА ДЛЯ БЫТИЯ final

Любые реализации могут изменять значение полей, если они не определены как окончательные. Тогда они станут частью реализации. Интерфейс - это чистая спецификация без какой-либо реализации.

ПРИЧИНА ДЛЯ БЫТИЯ static

Если они статические, то они принадлежат интерфейсу, а не объекту или типу объекта во время выполнения.

16 голосов
/ 29 октября 2009

Здесь есть пара пунктов, затерянных здесь:

То, что поля в интерфейсе неявно являются статическими final, не означает, что они должны быть константами времени компиляции или даже неизменяемыми. Вы можете определить, например,

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(Помните, что выполнение этого внутри определения аннотации может запутать javac , что связано с тем фактом, что вышеприведенное фактически компилируется в статический инициализатор.)

Кроме того, причина этого ограничения скорее стилистическая, чем техническая, и многие люди хотели бы, чтобы оно было смягчено .

9 голосов
/ 03 октября 2009

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

Поля должны быть окончательными, я думаю, потому что поля могут быть доступны для множества различных исполнителей, что позволяет их изменять, что может быть проблематично (как синхронизация). Также, чтобы избежать повторной реализации (скрыто).

Только мои мысли.

2 голосов
/ 03 апреля 2014

Я считаю требование, чтобы поля были окончательными, чрезмерно ограничительным и ошибкой разработчиков языка Java. Есть времена, например обработка дерева, когда вам нужно установить константы в реализации, которые необходимы для выполнения операций над объектом типа интерфейса. Выбор пути к коду в реализующем классе - это вызов. Обходной путь, который я использую, состоит в том, чтобы определить интерфейсную функцию и реализовать ее, возвращая литерал:

public interface iMine {
    String __ImplementationConstant();
    ...
}

public class AClass implements iMine {
    public String __ImplementationConstant(){
        return "AClass value for the Implementation Constant";
    }
    ...
}

public class BClass implements iMine {
    public String __ImplementationConstant(){
        return "BClass value for the Implementation Constant";
    }
    ...
}

Однако использовать этот синтаксис было бы проще, понятнее и менее подвержено аберрантной реализации:

public interface iMine {
    String __ImplementationConstant;
    ...
}

public class AClass implements iMine {
    public static String __ImplementationConstant =
        "AClass value for the Implementation Constant";
    ...
}

public class BClass implements iMine {
    public static String __ImplementationConstant =
        "BClass value for the Implementation Constant";
    ...
}
0 голосов
/ 02 ноября 2016

static * * 1004

Все (переменная или метод), которое static в Java, может быть вызвано как Classname.variablename или Classname.methodname или напрямую. Не обязательно вызывать его только с использованием имени объекта.

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

final

Это помогает поддерживать постоянное значение для переменной, поскольку ее нельзя переопределить в подклассах.

0 голосов
/ 04 октября 2016

Спецификация, контракты ... Машинная инструкция для доступа к полю использует адрес объекта плюс смещение поля. Поскольку классы могут реализовывать много интерфейсов, нет способа заставить неконечное поле интерфейса иметь одинаковое смещение во всех классах, расширяющих этот интерфейс. Поэтому должен быть реализован другой механизм доступа к полям: два обращения к памяти (получить смещение поля, получить значение поля) вместо одного плюс поддержка вида таблицы виртуальных полей (аналог таблицы виртуальных методов). Думаю, они просто не хотели усложнять jvm функциональностью, которую можно легко смоделировать с помощью существующих вещей (методов).

В scala у нас могут быть поля в интерфейсах, хотя внутренне они реализованы, как я объяснил выше (как методы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...