Чому всі поля в інтерфейсі неявно статичні та кінцеві?


100

Я просто намагаюся зрозуміти, чому всі поля, визначені в інтерфейсі, неявно staticі final. Ідея зберігати поля staticмає для мене сенс, оскільки ви не можете мати об'єкти інтерфейсу, але чому вони є final(неявно)?

Хтось знає, чому дизайнери Java пішли із створенням поля в інтерфейс staticі final?


На замітку для себе: Це статично, оскільки поля інтерфейсу не стануть частиною об'єкта, який його реалізує.
Дощ

Відповіді:


126

Інтерфейс не може мати поведінку або стан, оскільки він призначений лише для визначення договору про взаємодію, без деталей щодо імплементації. "Ніяка поведінка" не застосовується, не дозволяючи тілам методів / конструкторів або статичним / екземпляром ініціалізації блоків. "Ніякого стану" не застосовується, лише дозволяючи статичні кінцеві поля. Отже, клас може мати стан (статичний стан), але стан екземпляра не виводиться інтерфейсом.

BTW: Константа в Java визначається статичним кінцевим полем (а за умовою назва використовує UPPER_CASE_AND_UNDERSCORES).


54
Не обов'язково вірно, що кінцеві поля є константами; це гарантується лише для примітивних типів. Загалом, остаточне ключове слово просто означає, що місце пам'яті не зміниться.
Попс

8
Я не сказав, що кінцеві поля є константами, просто що константи - це кінцеві поля. Зауважте, що в інтерфейс дозволяється ставити непомітивне статичне остаточне поле. Незважаючи на те, що вміст цього поля може змінюватися, посилання на нього є постійним.
Адріан Костер

1
@AdriaanKoster Ви точно сказали, що остаточне поле є постійним: жоден стан не застосовується, лише дозволяючи константи. - з цього речення випливає, що всі заключні поля є постійними. Ви можете спробувати ще більше сперечатися з приводу використаних вами слів, але очевидно, що ваше твердження в оренді є оманливим.
Томаш Зато - Поновіть Моніку

2
Це повинен бути мій слабкий інтелект, але після шести років перегляду цієї відповіді, яка, як і моя найкраща оцінка, я все ще не розумію зауважень. Запропонуйте, будь ласка, іншу формулювання, тому що я не можу бачити нічого поганого.
Адріан Костер

Можливо, дизайнери java мали намір зробити інтерфейс без стану, але вони не змогли, оскільки поле примірника може бути модифікованим класом. Замість того, щоб визнати, що вони не змогли, вони вирішують примусити екземпляри поля static final, що максимально наближається до реальних (справжній C / C ++), constяк ви можете потрапити в Java. На жаль, це неявно і може призвести до плутанини для неексперта. (Я щойно зрозумів, що вони є, staticтому що я спостерігав ненавмисну ​​поведінку. Я дізнався, що вони finalлише з цієї відповіді.)
не користувач

27

Причина існування final

Будь-які реалізації можуть змінювати значення полів, якщо вони не визначені як кінцеві. Тоді вони стануть частиною реалізації. Інтерфейс - це чиста специфікація без будь-якої реалізації.

Причина існування static

Якщо вони статичні, то вони належать до інтерфейсу, а не до об'єкта, а також до типу виконання об'єкта.


18

Тут заглянуто кілька точок:

Тільки тому, що поля в інтерфейсі неявно статичні остаточні, не означає, що вони повинні бути константами часу компіляції або навіть незмінними. Ви можете визначити, наприклад

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

(Будьте уважні, якщо це робити всередині визначення приміток, можна заплутати javac , пов'язане з тим, що вищезазначене насправді компілюється в статичний ініціалізатор.)

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


9

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

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

Просто моя думка.


NawMan, твоє пояснення щодо "Поля повинні бути статичними ..." не має великого сенсу. Але ви мали рацію під тим, що "Поля повинні бути остаточними ..."
пік

1
Я не думаю, що він має рацію щодо причини, чому поля повинні бути остаточними. Дозволити різним виконавцям змінити поле не є проблематичним, оскільки в іншому випадку успадкування було б проблематичним. По словах Адріана, поля повинні бути остаточними, оскільки інтерфейс є і повинен бути без громадянства. Інтерфейс із станом в основному повинен бути абстрактним класом.
Axelle Ziegler

Якщо у вас є public staticполе, якого немає final, знаходять скарги findbugs (правильно!).
Том Хотін - тайклін

2

Я вважаю вимогу, щоб поля були остаточними як надмірно обмежувальні та помилки з боку дизайнерів мови 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

Специфікація, контракти ... Машинна інструкція для доступу до поля використовує адресу об'єкта плюс зміщення поля. Оскільки класи можуть реалізовувати безліч інтерфейсів, немає способу зробити поле, яке не завершує інтерфейс, для однакового зміщення у всіх класах, що розширюють цей інтерфейс. Тому необхідно запровадити різний механізм доступу до поля: два доступу до пам'яті (зміщення поля, отримання значення поля) замість одного плюс підтримка виду таблиці віртуальної поля (аналог таблиці віртуальних методів). Здається, вони просто не хотіли ускладнювати jvm для функціональності, який можна легко імітувати за допомогою існуючих матеріалів (методів).

У масштабі ми можемо мати поля в інтерфейсах, хоча внутрішньо вони реалізовані, як я пояснив вище (як методи).


-1

static:

Будь-яке (змінна чи метод), яке є staticна Java, може викликатися як Classname.variablenameабоClassname.methodname або безпосередньо. Не обов’язково викликати його лише за допомогою імені об'єкта.

В інтерфейсі об'єкти не можуть бути оголошені, і staticце дозволяє викликати змінні просто через ім'я класу без необхідності імені об'єкта.

final:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.