Чому на Java не існує функції Constant?


140

Я намагався визначити причину констант на Яві, я дізнався, що Java дозволяє нам оголошувати константи за допомогою finalключового слова.

Моє запитання, чому Java не ввела функцію Constant ( const). Оскільки багато людей кажуть, що це походить від C ++, у C ++ у нас є constключове слово.

Будь ласка, поділіться своїми думками.


2
Там єconst ключове слово, але не основна функція. Виправте свою назву та теги відповідно.
Маркіз Лорн

Відповіді:


142

Кожен раз, коли я переходжу від важкого кодування C ++ до Java, мені потрібно трохи часу, щоб пристосуватися до відсутності коректності у Java. Це використання constв C ++ значно відрізняється, ніж просто декларування постійних змінних, якщо ви цього не знали. По суті, він гарантує, що об'єкт є незмінним при доступі через спеціальний вид покажчика, який називається const-pointer Коли в Java, в місцях, де я зазвичай хочу повернути const-pointer, я замість цього повертаю посилання з типом інтерфейсу містять лише методи, які не повинні мати побічних ефектів. На жаль, це не виконується мовою.

Вікіпедія пропонує наступну інформацію з цього питання:

Цікаво, що специфікація мови Java розглядає const як зарезервоване ключове слово - тобто таке, яке не можна використовувати як ідентифікатор змінної - але не призначає йому ніякої семантики. Вважається, що резервування ключового слова відбулося з метою розширення мови Java, щоб включати методи const у стилі C ++ та вказівник на тип const. Квиток запиту на удосконалення в Процесі спільноти Java для впровадження правильності const у Java був закритий у 2005 році, що означає, що правильність const, ймовірно, ніколи не знайде свій шлях до офіційної специфікації Java.


10
finalХоча у Java схожий.
reinierpost

62
Ні, це не так. finalнаприклад, робота, зовсім інша, ніж constметоди C ++ .
dom0

7
@reinierpost finalКлючове слово для властивостей або змінних просто гарантує, що властивість або змінна призначена лише один раз . Ще можна змінити стан цього об'єкта, наприклад, назвавши якийсь метод із побічними ефектами. finalдещо схоже на розподіл стеків C ++ з точки зору перегляду об’єкту, а не на вказівник, але це все. Це звичайно на додаток до того, що dom0 вже говорив.
Тім

9
finalу Java, здається, працює як C ++ constдля типів значень, але більше схоже на C ++ non-const T&для еталонних типів
Mark K Cowan

1
final - це шизофренічне ключове слово. Хоча це перешкоджає перепризначенню, воно також використовується для викриття змінних закриттю. Я, можливо, хотів би запобігти перепризначенню, але не викривати ці змінні, але немає способу це зробити. На мою думку, це досить погано продумана мовна особливість.
Девід Бредлі

82

Що constозначає
По-перше, зрозумійте, що семантика ключового слова "const" означає різні речі для різних людей:

  • тільки для читання посилань - Java finalсемантики - сам посилальні змінний не може бути перепризначено до точки в іншу (наприклад , осередок пам'яті), але сам екземпляр є змінним
  • constдоступна для читання посилання - вказівник C / семантика посилань - означає, що ця посилання не може бути використана для зміни екземпляра (наприклад, не можна призначати змінні екземпляра, не може викликати зміни мутаційних методів) - впливає тільки на змінну посилання, тому посилання, що не відповідає const, вказує на той самий екземпляр може змінити екземпляр
  • незмінний об'єкт - означає, що сам екземпляр не може бути змінений - застосовується до екземпляра, тому будь-яка посилання, що не стосується const, не буде дозволена або не може бути використана для зміни примірника
  • якесь поєднання вищезазначеного ?
  • інші ?

Чому чи чому б не по-const
друге, якщо ви дійсно хочете зануритися в деякі з аргументів "про" проти "кон", дивіться дискусію в цьому запиті на покращення (RFE) "помилку". Ця RFE вимагає функцію "const" типу "для читання". Відкрита в 1999 році, а потім закрита / відхилена Sun у 2005 році, тема "const" активно обговорювалася:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4211070

Хоча є багато хороших аргументів з обох сторін, деякі часто цитовані (але не обов'язково переконливі чи чіткі) причини проти const:

  • може мати заплутану семантику, яку можна зловживати та / або зловживати (див. Що constозначає вище)
  • може дублювати можливості, доступні в іншому випадку (наприклад, проектування незмінного класу, використовуючи незмінний інтерфейс)
  • Це може бути повзуча особливість, що призводить до необхідності інших смислових змін, таких як підтримка передачі об'єктів за значенням

Перш ніж хтось спробує обговорити мене, чи це хороші чи погані причини, зауважте, що це не мої причини . Вони просто "суть" однієї з причин, за якими я ухилився від зневірення дискусії щодо RFE. Я не обов'язково погоджуюся з ними сам - я просто намагаюся сказати, чому деякі люди (не я) можуть вважати, що constключове слово може бути не дуже хорошою ідеєю. Особисто я хотів би, щоб більше «const» семантики було введено до мови однозначно.


2
+1 лише для другої частини вашої відповіді. Багато багатьох ключових слів мають нетривіальну семантику. Це volatileтак просто зрозуміти? Або final? Мех.
einpoklum

OTOH, Java була розроблена для використання якомога менше таких нетривіальних функцій. І я не кажу, що вони досягли цієї мети (або що Java не відійшла від цієї мети). Але виключення з цієї причини, можливо, все-таки мала заслугу. Те, що є інші складні речі, є тим більше причин не вводити більше ( інакше ти закінчиш мову D).
Maarten Bodewes

7

const в C ++ не означає, що значення є константою.

const в C ++ випливає, що клієнт договору зобов’язується не змінювати його вартість.

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

Оскільки Java розроблялася з самого початку для підтримки потоку і блокування одночасності, вона не додала плутанини, перевантажуючи термін, щоб мати семантику, яка finalє.

наприклад:

#include <iostream>

int main ()
{
    volatile const int x = 42;

    std::cout << x << std::endl;

    *const_cast<int*>(&x) = 7;

    std::cout << x << std::endl;

    return 0;
}

виходи 42, то 7.

Хоча xпозначений як const, як створений псевдонім, xякий не є суворим, не є постійною. Не кожен компілятор вимагає volatileтакої поведінки (хоча кожному компілятору дозволено вбудовувати константу)

При більш складних системах ви отримуєте псевдоніми const / non-const без використання const_cast, тому ввівшись у звичку думати, що const означає, що щось не зміниться, стає все більш небезпечним. constозначає лише, що ваш код не може змінити його без виступу, не те, що значення є постійним.


3
const int x = 42; - х є константою

2
@Neil Якщо у вас є один об'єкт або змінна, псевдоніми як вказівниками const, так і non-const, то значення псевдоніму const може бути змінено псевдонімом non-const. Тому constне означає, що значення є постійним. Це означає, що клієнт значення обмежений, щоб не мутувати його. У вашому прикладі немає псевдоніму, тому всі користувачі знаходяться під однаковим обмеженням. Це взагалі не так. constвпливає на клієнтів, а не на значення - воно говорить, що ви не можете його змінити, не те, що воно не зміниться.
Піт Кіркхем

1
Правильність конкуренції - це те, що повинен робити програміст , а не те, що вони можуть зробити . Я думаю, що ви, схоже, все зрозуміли. Просто хотілося додати пару центів, які могли б зацікавити причинного читача: Дизайнерські шаблони, як, immutable interfaceі immutable objectє іншим способом (можна передати за допомогою кадра та відображення) для імітації const у Java. "Справжній" const може бути виконаний із SealedObject , на жаль, це знищує випадок використання нашого об'єкта.
Мартін Андерссон

6
Слід зазначити, що результат вашої програми не визначений. const_cast не існує для зміни змінних const, це для передачі const змінних в API, які не є правильними const, але також не змінюють значення. Я думаю, що звичка думати, що щось const не зміниться, є хорошою, тому що якщо вони зміниться, це означає, що ваша програма містить хаки, які можуть зламатися в будь-який час залежно від використовуваного компілятора.
Цигон

1
Модифікація значення, що народжується до постійної, - це невизначена поведінка. Ваш диск може бути вже відформатований.
Чже Ян

5

Це трохи старе запитання, але я подумав, що все-таки вкладу свої 2 копійки, оскільки ця тема сьогодні з'явилася в розмові.

Це точно не відповідає чому не існує const? але як зробити ваші заняття непорушними. (На жаль, у мене ще недостатньо репутації, щоб розмістити коментар до прийнятої відповіді)

Спосіб гарантувати незмінність об’єкта - це більш ретельно спроектувати свої класи, щоб вони були незмінні. Для цього потрібно трохи більше турбот, ніж клас, що змінюється.

Це повертається до ефективної Java- позиції 15 Джоша Блоха - Мінімізація змінності . Якщо ви ще не читали книгу, візьміть копію та прочитайте її кілька разів, я гарантую, що вона збільшить вашу образну «гру на Java» .

У пункті 15 Bloch пропонують обмежити можливість зміни класів, щоб забезпечити стан об'єкта.

Цитувати книгу безпосередньо:

Незмінний клас - це просто клас, екземпляри якого неможливо змінити. Вся інформація, що міститься в кожному екземплярі, надається при її створенні та фіксується протягом життя об’єкта. Бібліотеки платформи Java містять безліч незмінних класів, включаючи String, примітивні класи в коробці, а також BigInteger та BigDecimal. Для цього є багато вагомих причин: Незмінні класи легше проектувати, впроваджувати та використовувати, ніж класи, що змінюються. Вони менш схильні до помилок і більш безпечні.

Потім Bloch описує, як зробити свої класи незмінними, дотримуючись 5 простих правил:

  1. Не надайте жодних методів, що змінюють стан об'єкта (тобто сеттери, мутатори ака )
  2. Переконайтесь, що клас не може бути розширений (це означає оголошення класу як final).
  3. Зробіть усі поля final.
  4. Зробіть усі поля private.
  5. Забезпечте виключний доступ до будь-яких змінних компонентів. (роблячи захисні копії об'єктів)

Для більш детальної інформації я настійно рекомендую забрати примірник книги.


3
const у C ++ набагато гнучкіший, ніж повномасштабна незмінність. У певному сенсі «const» може розглядатися як «незмінний у цьому конкретному контексті». Приклад: у мене клас, який не змінюється, але я хочу переконатися, що він не змінюється через певні публічні API. Створення інтерфейсу (і повернення його для цього публічного API), як запропонував Gunslinger47, досягає того ж, що і в Java, але хлопчик - це негарно (і так - більшість розробників Java ігнорує, що призводить до значної непотрібності). .
Заєць без клопів

3

Семантика C ++ constсильно відрізняється від Java final. Якби дизайнери використовували constце, це було б надмірно заплутаним.

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


-1

Існує спосіб створити "const" змінні в Java, але тільки для конкретних класів. Просто визначте клас із кінцевими властивостями та підкласуйте його. Потім використовуйте базовий клас, де ви хочете використовувати "const". Так само, якщо вам потрібно використовувати методи "const", додайте їх до базового класу. Компілятор не дозволить вам змінювати те, що, на його думку, є кінцевими методами базового класу, але він буде читати та викликати методи на підкласі.


Чи можете ви надати приклад цього?
NO_NAME

клас MYString реалізує GetString {приватний фінал String aaaa; public String getString (); } реалізує клас MutableString GetString {private String aaaa2; public String getString (); public String setString ()}
користувач1122069

-2

Існуватиме два способи визначення констант - constпричому static finalз точно такою ж семантикою. Крім того, static finalописує поведінку краще, ніжconst


@Bozho, ти сказав кращу поведінку, ніж Конст, як це? Ви можете поділитися будь-яким прикладом
gmhk

ну змінна є static(не належить до конкретного примірника) і finalне може бути змінена.
Божо

-2

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

protected static final int cOTHER = 0;
protected static final int cRPM = 1;
protected static final int cSPEED = 2;
protected static final int cTPS = 3;
protected int DataItemEnum = 0;

public static final int INVALID_PIN = -1;
public static final int LED_PIN = 0;

Захищений від оптимізації на основі чуток, тому що я почув слух, що це неефективна стратегія.
afarley

Я зняв чутку з відповіді. ви все ще можете використовувати статичний остаточний int для створення коду стилю const.
hamish

Гаразд, я видалив свій потік. Можливо, деякі інші головні запитання стосуються твердження перемикача (яке воно стосується решти вашого прикладу?)
afarley

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