Почему все поля в интерфейсе неявно статичны и окончательны?

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

Любой знает, почему дизайнеры Java пошли на создание полей в интерфейсе static а также final?

7 ответов

Решение

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

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

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

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

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

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

Здесь есть пара моментов:

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

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

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

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

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

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

Просто моя мысль.

Я считаю требование, чтобы поля были окончательными, чрезмерно ограничительным и ошибкой разработчиков языка 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";
    ...
}

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

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

static:

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

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

final:

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

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