2010-04-29 3 views
121

Я пытался определить причину постоянных в Java Я узнал, что Java позволяет нам объявлять константы, используя ключевое слово final.Почему в Java нет постоянной функции?

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

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

+1

Здесь * есть * ключевое слово 'const', но нет основной функции. Исправлено соответствующее название и теги. – EJP

ответ

127

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

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

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

+9

«final» Java похож. – reinierpost

+44

Нет, это не так. Например, метод 'final' полностью отличается от методов' 'const''. – dom0

+3

@reinierpost Ключевое слово 'final' * по свойствам или переменным * просто гарантирует, что свойство или переменная присваивается только ** **. Можно было бы изменить состояние этого объекта, например, вызвав некоторый метод с побочными эффектами. 'final' несколько похож на распределение стека C++ в терминах ссылки на объект, а не на указатель, но это все. Это, конечно же, в дополнение к тому, что уже говорило dom0. – Tim

9

Const не используется, потому что вы не можете обеспечить тот факт, что значение является постоянным в Java. Поэтому это было бы неправильным. Финал - возможно (хотя и субъективно) - лучшее имя, так как он указывает, что переменная является окончательной ссылкой (ее нельзя переназначить).

В качестве аргумента const является зарезервированное, но неиспользуемое ключевое слово в Java.

+14

Вы не можете принудительно выполнить это, потому что нет 'const', что позволит использовать механизм для его принудительного применения. – einpoklum

+2

@einpoklum Правда, это действительно кругный аргумент. :) – kalj

+1

@kalj: И все же +15 голосов ... – einpoklum

-1

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

+0

@ Божо, вы сказали, что лучше, чем Const, как он? вы можете поделиться любым примером – gmhk

+0

ну, переменная 'static' (не принадлежащая конкретному экземпляру) и' final' - не может быть изменена. – Bozho

3

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

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

5

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

+3

const int x = 42; - x является константой – 2010-04-29 08:39:48

+0

@Neil Я думаю, что он говорит об объектах –

+0

@andy Работает одинаково для объектов. – 2010-04-29 08:57:34

76

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

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

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

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

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

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

Перед тем, кто пытается спорить со мной о будь то хорошие или плохие причины, обратите внимание, что это не по моим причинам. Это просто «сущность» некоторых причин, по которым я почерпнул из-за сглаживания дискуссии на радиопомех. Я не обязательно соглашаюсь с ними сам - я просто пытаюсь назвать, почему некоторые люди (а не я) могут чувствовать ключевое слово const, возможно, не очень хорошая идея. Лично мне хотелось бы, чтобы более семантика «const» была введена на язык недвусмысленным образом.

+2

+1 только для второй части вашего ответа. Многие ключевые слова имеют нетривиальную семантику. Неужели 'volatile' настолько прост для понимания? Или «финал»? Мех. – einpoklum

-1

Я слышал слухи, что использование Enums в Java плохо для производительности игры. Я не знаю, почему. Const будет работать лучше ...

примеров использования ФИКСА реальной жизни в Java ... просто написать код, как это ... , а затем ваши заявления переключателя будут работать без ропота ..

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; 

.

switch (this.DataItemEnum) { 
    case cRPM: 
     percent = (Value - 0.001*Min)/(Max - Min); 
     break; 
    default: 
     percent = (Value - Min)/(Max - Min); 
     break 
} 
+0

Что не так с использованием статического финала? – hamish

-1

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

+0

Можете ли вы привести пример этого, пожалуйста? –

+0

класс MYString реализует GetString { закрытый финал String aaaa; public String getString(); } класс MutableString реализует GetString { private String aaaa2; public String getString(); public String setString() } – user1122069

4

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

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

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

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

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

Цитирую книгу непосредственно:

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

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

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

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

+0

const на C++ является более гибким, чем полномасштабная неизменность. В некотором смысле «const» можно рассматривать как «неизменяемый в этом конкретном контексте». Пример. У меня есть класс, который не является неизменным, но я хочу убедиться, что он не изменяется через определенные публичные API. Создание интерфейса (и возвращение его для этого общедоступного API), как это было предложено Gunslinger47, дает то же самое на Java, но мальчик - он уродливый (и так - он игнорируется большинством разработчиков Java, что приводит к значительному ненужному беспорядку). , –

 Смежные вопросы

  • Нет связанных вопросов^_^