Почему в Java нет функции Constant? - PullRequest
132 голосов
/ 29 апреля 2010

Я пытался определить причину констант в Java Я узнал, что Java позволяет нам объявлять константы с помощью ключевого слова final.

У меня вопрос, почему в Java не появилась функция Constant (const). Поскольку многие люди говорят, что это пришло из C ++, в C ++ у нас есть ключевое слово const.

Пожалуйста, поделитесь своими мыслями.

Ответы [ 8 ]

136 голосов
/ 29 апреля 2010

Каждый раз, когда я перехожу от тяжелого кодирования C ++ к Java, мне требуется некоторое время, чтобы приспособиться к отсутствию const -корректности в Java. Такое использование const в C ++ сильно отличается от простого объявления константных переменных, если вы не знали. По сути, это гарантирует, что объект является неизменным при доступе через специальный вид указателя, называемый const-pointer. Когда в Java, в местах, где я обычно хотел бы вернуть const-указатель, я вместо этого возвращаю ссылку с типом интерфейса содержит только методы, которые не должны иметь побочных эффектов. К сожалению, это не навязывается языком.

Википедия предлагает следующую информацию по теме:

Интересно, что спецификация языка Java рассматривает const как зарезервированное ключевое слово, то есть то, которое нельзя использовать в качестве идентификатора переменной, но не назначает ему семантику. Предполагается, что резервирование ключевого слова произошло, чтобы позволить расширению языка Java включить методы const в стиле C ++ и указатель на тип const. Запрос на усовершенствование в Java Community Process для реализации правильности констант в Java был закрыт в 2005 году, из чего следует, что корректность констант, вероятно, никогда не найдет свое место в официальной спецификации Java.

81 голосов
/ 29 апреля 2010

Что означает const
Во-первых, поймите, что семантика ключевого слова const означает разные вещи для разных людей:

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

Почему или почему нет const
Во-вторых, если вы действительно хотите разобраться с некоторыми аргументами «за» и «против», посмотрите обсуждение под «ошибкой» в этом запросе на улучшение (RFE). Этот RFE запрашивает функцию «const» типа «только для чтения». Открытая в 1999 году, а затем закрытая / отклоненная Sun в 2005 году, тема «const» активно обсуждалась:

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

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

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

Прежде чем кто-либо попытается обсудить меня, являются ли это хорошими или плохими причинами, обратите внимание, что это не мои причины . Они просто "суть" некоторых из причин, которые я почерпнул из разговоров о РСЕ. Я не обязательно с ними согласен - я просто пытаюсь процитировать, почему некоторые люди (не я) могут чувствовать, что ключевое слово const может быть не очень хорошей идеей. Лично я хотел бы, чтобы больше "const" семантики было введено в язык однозначным образом.

7 голосов
/ 29 апреля 2010

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_cast, поэтому привыкание думать, что const означает, что что-то не изменится, становится все более опасным. const просто означает, что ваш код не может изменить его без приведения, а не то, что значение является постоянным.

5 голосов
/ 07 июня 2016

Это немного старый вопрос, но я думал, что все равно внесу свои 2 цента, так как эта тема возникла сегодня в разговоре.

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

Чтобы гарантировать неизменность объекта, нужно разработать классы более тщательно, чтобы они были неизменяемыми. Это требует немного большей осторожности, чем изменяемый класс.

Это восходит к Effective Java Джоша Блоха Пункт 15 - Минимизируйте изменчивость . Если вы еще не читали книгу, возьмите копию и прочитайте ее несколько раз, и я гарантирую, что она поднимет вашу образную «java игру» .

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

Чтобы процитировать книгу напрямую:

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

Затем Блох описывает, как сделать ваши классы неизменяемыми, следуя 5 простым правилам:

  1. Не предоставляйте никаких методов, которые изменяют состояние объекта (например, setters, aka mutators )
  2. Убедитесь, что класс не может быть расширен (это означает, что сам класс объявлен как final).
  3. Сделать все поля final.
  4. Сделать все поля private.
  5. Обеспечить эксклюзивный доступ к любым изменяемым компонентам. (делая защитные копии объектов)

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

3 голосов
/ 29 апреля 2010

Семантика C ++ const очень отличается от Java final.Если бы дизайнеры использовали const, это было бы излишне запутанным.

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

0 голосов
/ 07 марта 2016

Существует способ создания «постоянных» переменных в Java, но только для определенных классов. Просто определите класс с конечными свойствами и создайте его подкласс. Затем используйте базовый класс, где вы хотели бы использовать «const». Аналогичным образом, если вам нужно использовать методы «const», добавьте их в базовый класс. Компилятор не позволит вам изменить то, что он считает конечными методами базового класса, но он будет читать и вызывать методы подкласса.

0 голосов
/ 13 апреля 2013

Вы можете использовать static final для создания чего-то, что работает аналогично 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;
0 голосов
/ 29 апреля 2010

Существуют два способа определения констант - const и static final с точно такой же семантикой. Кроме того, static final описывает поведение лучше, чем const

...