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

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

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

Ответ 1

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

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

Ответ 2

Причина существования final

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

Причина существования static

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

Ответ 3

Здесь есть несколько моментов:

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

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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";
    ...
}

Ответ 6

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

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

Ответ 7

static

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

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

final

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