Я видел такие примеры:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
и предположил, что у меня может быть класс Constants, чтобы обернуть константы, объявив их статическими финальными. Я практически не знаю Java, и мне интересно, если это лучший способ создания констант.
Ответы:
Это вполне приемлемо, возможно, даже стандарт.
где
TYPE
тип,NAME
имя во всех заглавных буквах с подчеркиванием для пробелов иVALUE
постоянное значение;Я настоятельно рекомендую НЕ помещать ваши константы в их собственные классы или интерфейсы.
Примечание: переменные, объявленные как final и изменяемые, все еще могут быть изменены; однако переменная никогда не может указывать на другой объект.
Например:
Это законно, и
ORIGIN
тогда будет точка в (3, 0).источник
Я бы настоятельно рекомендовал не иметь единого класса констант. В то время это может показаться хорошей идеей, но когда разработчики отказываются документировать константы, и класс увеличивается до 500 констант, которые вообще не связаны друг с другом (относящихся к совершенно другим аспектам приложения), это обычно превращается в файл констант, который полностью не читается. Вместо:
источник
Это плохая практика , чтобы использовать интерфейсы только , чтобы держать константы (названный постоянной шаблон интерфейса Джош Блох). Вот что советует Джош:
Пример:
О соглашении об именах:
источник
abstract
нотацию для класса вместо частного конструктора.abstract
вместо частного конструктора не полностью предотвращает создание экземпляров, потому что можно создать его подкласс и создать экземпляр класса (не то, чтобы это было хорошей идеей, но это возможно). @ToolmakerSteve Вы не можете создать подкласс класса с приватным конструктором (по крайней мере, без большого неудачного взлома), потому что конструктор подкласса должен вызвать (теперь приватный) конструктор своего суперкласса. Таким образом, отмечать этоfinal
не нужно (но, возможно, более явно).В Effective Java (2-е издание) для констант рекомендуется использовать перечисления вместо статических целочисленных значений.
Хорошая рецензия на перечисления в Java здесь: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
Обратите внимание, что в конце этой статьи поставлен вопрос:
С ответом:
источник
Просто избегайте использования интерфейса:
Это заманчиво, но нарушает инкапсуляцию и стирает различия между определениями классов.
источник
Я использую следующий подход:
Чем, например, я пользуюсь,
Constants.DB.Connection.URL
чтобы получить константу. Это выглядит более "объектно-ориентированным", как для меня.источник
Создание статических конечных констант в отдельном классе может привести к неприятностям. Компилятор Java фактически оптимизирует это и поместит фактическое значение константы в любой класс, который ссылается на нее.
Если вы позже измените класс «Константы» и не будете выполнять перекомпиляцию других классов, которые ссылаются на этот класс, вы получите комбинацию старых и новых значений.
Вместо того, чтобы думать о них как о константах, думайте о них как о параметрах конфигурации и создавайте класс для управления ими. Пусть значения не являются окончательными, и даже подумайте об использовании геттеров. В будущем, когда вы определите, что некоторые из этих параметров должны настраиваться пользователем или администратором, это будет гораздо проще сделать.
источник
Ошибка номер один, которую вы можете совершить, - это создание глобально доступного класса с общим именем, например, Constants. Это просто завален мусором, и вы теряете все возможности выяснить, какая часть вашей системы использует эти константы.
Вместо этого константы должны входить в класс, который «владеет» ими. У вас есть константа под названием TIMEOUT? Вероятно, он должен перейти в ваш класс Communications () или Connection (). MAX_BAD_LOGINS_PER_HOUR? Заходит в пользователя (). И так далее.
Другим возможным использованием являются файлы .properties Java, когда «константы» могут быть определены во время выполнения, но их нелегко изменить пользователем. Вы можете упаковать их в ваши .jars и ссылаться на них с помощью класса resourceLoader.
источник
Это правильный путь.
Обычно константы не хранятся в отдельных классах «Константы», потому что их нельзя обнаружить. Если константа относится к текущему классу, их хранение помогает следующему разработчику.
источник
Как насчет перечисления?
источник
Я предпочитаю использовать геттеры, а не константы. Эти геттеры могут возвращать значения констант, например
public int getMaxConnections() {return 10;}
, но все, что нуждается в константе, будет проходить через геттер.Одним из преимуществ является то, что если ваша программа перерастает константу - вы обнаружите, что она должна быть настраиваемой - вы можете просто изменить способ получения константой.
Другое преимущество заключается в том, что для изменения константы не нужно перекомпилировать все, что ее использует. Когда вы ссылаетесь на статическое конечное поле, значение этой константы компилируется в любой байт-код, который ссылается на него.
источник
Я согласен, что использование интерфейса - это не тот путь. Избегание этого шаблона даже имеет свой собственный элемент (# 18) в Эффективной Java Блоха .
Аргумент Блоха в отношении константного шаблона интерфейса заключается в том, что использование констант - это деталь реализации, но реализация интерфейса для их использования раскрывает эту деталь реализации в экспортированном API.
public|private static final TYPE NAME = VALUE;
Модель является хорошим способом объявить константу. Лично я думаю, что лучше избегать создания отдельного класса для размещения всех ваших констант, но я никогда не видел причины не делать этого, кроме личных предпочтений и стиля.Если ваши константы могут быть смоделированы как перечисление, рассмотрите перечисление структуру доступную в 1.5 или более поздней.
Если вы используете версию более раннюю, чем 1.5, вы все равно можете извлечь перечисления с безопасным типом, используя обычные классы Java. (Смотрите этот сайт для более подробной информации).
источник
Основываясь на комментариях выше, я думаю, что это хороший подход для изменения старомодного глобального константного класса (имеющего открытые статические конечные переменные) на его эквивалентный перечислению таким образом:
Итак, я могу отнести их к как:
источник
Хороший объектно-ориентированный дизайн не должен нуждаться во многих общедоступных константах. Большинство констант должны быть инкапсулированы в классе, который нуждается в них для выполнения своей работы.
источник
Есть определенное количество мнений, чтобы ответить на это. Начнем с того, что константы в Java обычно объявляются как public, static и final. Ниже приведены причины:
Я бы никогда не использовал интерфейс для объекта доступа / объекта CONSTANTS просто потому, что обычно ожидается, что интерфейсы будут реализованы. Разве это не выглядит смешно:
Вместо этого я бы выбрал несколько разных способов, основанных на некоторых небольших компромиссах, и поэтому это зависит от того, что вам нужно:
источник
Один подход, которого мы должны избегать : использование интерфейсов для определения констант.
Создание интерфейса, специально предназначенного для объявления констант, на самом деле является наихудшей вещью: оно побеждает причину, по которой были разработаны интерфейсы: определение метода (ов) контракта.
Даже если интерфейс уже существует для удовлетворения конкретной потребности, объявление констант в них не имеет смысла, так как константы не должны составлять часть API и контракта, предоставляемого клиентским классам.
Чтобы упростить, у нас есть в целом 4 действительных подхода .
С
static final String/Integer
полем:С
Java 5 enum
:TLDR: Какой способ лучше всего и где найти константы?
В большинстве случаев путь enum, вероятно, более тонкий, чем
static final String/Integer
путь, и лично я считаю, что этотstatic final String/Integer
путь следует использовать только в том случае, если у нас есть веские причины не использовать enum.Что касается того, где мы должны объявлять постоянные значения, идея состоит в том, чтобы искать, существует ли единственный существующий класс, который обладает определенной и сильной функциональной связностью с постоянными значениями. Если мы найдем такой класс, мы должны использовать его в качестве держателя констант . В противном случае константа не должна быть связана ни с одним конкретным классом.
static final String
/static final Integer
противenum
Использование Enums действительно способ, который настоятельно рекомендуется.
Перечисления имеют большое преимущество перед
String
илиInteger
постоянное поле.Они устанавливают более жесткие ограничения компиляции. Если вы определите метод, который принимает перечисление в качестве параметра, вы можете передать только значение перечисления, определенное в классе перечисления (или ноль).
С помощью String и Integer вы можете заменить их любыми значениями совместимого типа, и компиляция будет в порядке, даже если значение не является определенной константой в
static final String
/static final Integer
полях .Например, ниже двух констант, определенных в классе как
static final String
поля:Вот метод, который ожидает иметь одну из этих констант в качестве параметра:
Вы можете вызвать это следующим образом:
или
Но никакое ограничение компиляции не мешает вам вызывать его следующим образом:
Вы будете иметь ошибку только во время выполнения и только если вы делаете за раз проверку переданного значения.
При использовании enum проверки не требуются, поскольку клиент может передать только значение enum в параметре enum.
Например, здесь два значения, определенные в классе enum (поэтому постоянные из коробки):
Вот метод, который ожидает иметь одно из этих значений перечисления в качестве параметра:
Вы можете вызвать это следующим образом:
или
Но компиляция никогда не позволит вам вызвать его таким образом:
Где мы должны объявить константы?
Если ваше приложение содержит один существующий класс, который обладает определенной и сильной функциональной связью с постоянными значениями, то 1) и 2) кажутся более интуитивными.
Как правило, это облегчает использование констант, если они объявлены в главном классе, который ими манипулирует, или у которого есть имя, и очень естественно догадываться, что мы найдем его внутри.
Например, в библиотеке JDK экспоненциальные значения и значения констант pi объявляются в классе, который объявляет не только константные объявления (
java.lang.Math
).Клиенты, использующие математические функции, часто полагаются на
Math
класс. Таким образом, они могут достаточно легко найти константы, а также могут вспомнить, гдеE
и какPI
они определены очень естественным образом.Если ваше приложение не содержит существующего класса, который имеет очень специфическую и сильную функциональную сплоченность с постоянными значениями, то варианты 1 и 2 будут казаться более интуитивными.
Как правило, это не облегчает использование констант, если они объявлены в одном классе, который ими манипулирует, в то время как у нас есть также 3 или 4 других класса, которые манипулируют ими так же, как и ни один из этих классов не кажется более естественным, чем другие. постоянные значения хоста.
Здесь определение пользовательского класса для хранения только постоянных значений имеет смысл.
Например, в библиотеке JDK
java.util.concurrent.TimeUnit
перечисление не объявлено в определенном классе, поскольку на самом деле не существует одного и только одного конкретного класса JDK, который представляется наиболее интуитивно понятным для его хранения:Многие классы объявляются в
java.util.concurrent
использовании их:BlockingQueue
,ArrayBlockingQueue<E>
,CompletableFuture
,ExecutorService
, ... и на самом деле не один из них не представляется более целесообразным провести перечисление.источник
Константа любого типа может быть объявлена путем создания неизменного свойства внутри класса (то есть переменной-члена с
final
модификатором). Как правило,static
иpublic
модификаторы также предоставляются.Существует множество приложений, в которых значение константы указывает выбор из n-кортежей (например, перечисление ) вариантов выбора. В нашем примере мы можем выбрать определение перечисляемого типа, которое ограничит возможные присвоенные значения (то есть улучшенную безопасность типов ):
источник
Единственный, универсальный класс констант - плохая идея. Константы должны быть сгруппированы вместе с классом, с которым они наиболее логически связаны.
Вместо того, чтобы использовать какие-либо переменные (особенно перечисления), я бы предложил использовать методы. Создайте метод с тем же именем, что и у переменной, и сделайте так, чтобы он возвращал значение, которое вы присвоили переменной. Теперь удалите переменную и замените все ссылки на нее вызовами только что созданного вами метода. Если вы чувствуете, что константа достаточно универсальна, и вам не нужно создавать экземпляр класса просто для ее использования, тогда сделайте метод константы методом класса.
источник
FWIW, значение тайм-аута в секундах, вероятно, должно быть параметром конфигурации (считанным из файла свойств или путем внедрения, как в Spring), а не константой.
источник
В чем разница
1.
2.
и использовать
MyGlobalConstants.TIMEOUT_IN_SECS
везде, где нам нужна эта константа. Я думаю, что оба одинаковы.источник
Я бы не назвал класс тем же (кроме регистра), что и константой ... У меня был бы как минимум один класс «Настройки», или «Значения», или «Константы», где будут жить все константы. Если бы у меня их было много, я бы сгруппировал их в классы логических констант (UserSettings, AppSettings и т. Д.)
источник
Чтобы продвинуться дальше, вы можете поместить глобально используемые константы в интерфейс, чтобы их можно было использовать во всей системе. Например
Но не воплощайте это в жизнь. Просто обратитесь к ним прямо в коде через полное имя класса.
источник
Для констант Enum - лучший выбор IMHO. Вот пример
открытый класс myClass {
источник
Один из способов сделать это - создать класс «Global» с постоянными значениями и выполнить статический импорт в классы, которым требуется доступ к константе.
источник
static final
это мое предпочтение, я бы использовал только,enum
если бы элемент был действительно перечислимым.источник
я использую
static final
чтобы объявить константы и использовать обозначение имен ALL_CAPS. Я видел довольно много реальных случаев, когда все константы объединялись в интерфейс. Несколько постов справедливо назвали это плохой практикой, в первую очередь потому, что интерфейс не для этого. Интерфейс должен обеспечивать выполнение контракта и не должен быть местом для помещения не связанных между собой констант. Объединение его в класс, экземпляр которого не может быть создан (с помощью частного конструктора), тоже хорошо, если семантика констант не принадлежит конкретному классу ( эс). Я всегда помещаю константу в класс, с которым она больше всего связана, потому что это имеет смысл и также легко поддерживается.Перечисления являются хорошим выбором для представления диапазона значений, но если вы храните автономные константы с акцентом на абсолютное значение (например, TIMEOUT = 100 мс), вы можете просто пойти на
static final
подход.источник
Я согласен с тем, что говорят большинство, лучше всего использовать перечисления при работе с коллекцией констант. Однако, если вы программируете на Android, есть лучшее решение: IntDef Annotation .
Аннотация IntDef превосходит перечисления одним простым способом, она занимает значительно меньше места, поскольку является просто маркером времени компиляции. Он не является классом и не имеет свойства автоматического преобразования строк.
источник
Это дурная привычка и очень назойливый практик цитировать Джошуа~d Блох , не понимая основной грунт нулевого фундаментализма.
Я ничего не читал Джошуа Блох, так что либо
Как и в библейском фундаментализме, все библейские законы могут быть обобщены
и так же фундаментализм разработки программного обеспечения может быть суммирован
Кроме того, среди библейских фундаменталистских кругов обращается сильное и разумное следствие.
Точно так же, если вы не уважаете себя как программиста и просто принимаете высказывания и пророчества некоторых программистов-гуру, не ставя под сомнение основы, ваши цитаты и опора на Джошуа Блоха (и тому подобное) не имеют смысла. И поэтому вы на самом деле не будете уважать своих коллег-программистов.
Основные законы программирования
Константы шаблона интерфейса - плохая привычка ???
В какие законы фундаментально эффективного и ответственного программирования входит этот религиозный указ?
Просто прочитайте статью в Википедии о константах шаблона интерфейса ( https://en.wikipedia.org/wiki/Constant_interface ), и глупо оправдывать ее константы шаблона интерфейса.
Whatif-нет IDE? Кто на земле как программист не будет использовать IDE? Большинство из нас - программисты, которые предпочитают не доказывать наличие мачо-аскетического выживания, избегая использования IDE.
Загрязняет пространство имен переменными, не используемыми в текущей области? Это могут быть сторонники этого мнения
Использование интерфейсов для принудительного применения констант является злоупотреблением интерфейсами. Сторонники таких имеют плохую привычку
Трудно, если не невозможно, преобразовать интерфейсы в реализованные классы в будущем. Хах .... хммм ... ???
Каковы бы ни были оправдания, НЕТ ДЕЙСТВИТЕЛЬНОГО ПРИЧИНА, когда дело доходит до ФУНДАМЕНТАЛЬНО ЭФФЕКТИВНОЙ разработки программного обеспечения, чтобы делегитимизировать или вообще препятствовать использованию констант интерфейса.
Неважно, каковы были первоначальные намерения и психические состояния отцов-основателей, которые разработали Конституцию Соединенных Штатов. Мы могли бы обсудить первоначальные намерения отцов-основателей, но все, что меня волнует, - это письменные заявления Конституции США. И каждый гражданин США несет ответственность за использование письменного литературного фундаментализма, а не неписаных оснований Конституции США.
Точно так же меня не волнует, какие «оригинальные» намерения основатели платформы Java и языка программирования имели для интерфейса. Меня волнуют эффективные функции, предоставляемые спецификацией Java, и я намерен использовать эти функции в полной мере, чтобы помочь мне выполнить фундаментальные законы ответственного программирования. Мне все равно, если меня воспринимают как «нарушающее намерение интерфейсов». Меня не волнует, что Гослинг или кто-то другой Блох говорит о «правильном способе использования Java», если только то, что они говорят, не нарушает мою потребность в ЭФФЕКТИВНОМ выполнении основ.
Основой является нормализация модели данных
Неважно, как ваша модель данных размещается или передается. Используете ли вы интерфейсы, перечисления или другие, реляционные или не-SQL, если вы не понимаете необходимости и процесса нормализации модели данных.
Сначала мы должны определить и нормализовать модель данных набора процессов. И когда у нас есть согласованная модель данных, ТОЛЬКО тогда мы можем использовать поток процессов его компонентов, чтобы определить функциональное поведение и блоки процессов в области или области приложений. И только тогда мы можем определить API каждого функционального процесса.
Даже аспекты нормализации данных, предложенные EF Codd, в настоящее время подвергаются серьезным и серьезным испытаниям. Например, его заявление о 1NF было подвергнуто критике как неоднозначное, смещенное и чрезмерно упрощенное, как и остальные его заявления, особенно в связи с появлением современных услуг передачи данных, технологий репо и передачи. IMO, заявления EF Codd должны быть полностью исключены, и должен быть разработан новый набор более математически правдоподобных утверждений.
Ярким недостатком Э. Ф. Кодда и причиной его несоответствия эффективному человеческому пониманию является его вера в то, что воспринимаемые человеком многомерные данные с изменчивыми измерениями могут быть эффективно восприняты посредством набора кусочных 2-мерных отображений.
Основы нормализации данных
Что Э. Ф. Кодд не смог выразить.
В рамках каждой последовательной модели данных это последовательный градуированный порядок достижения согласованности модели данных.
В области или сетке взаимообслуживающих компонентных приложений должна существовать одна и только одна согласованная модель данных, или существует средство, позволяющее модели / версии данных идентифицировать себя.
Мы все еще спрашиваем, можем ли мы использовать интерфейсные константы? В самом деле ?
На карту поставлены более важные вопросы нормализации данных, чем этот обыденный вопрос. Если вы не решите эти проблемы, путаница, которую, по вашему мнению, вызывают константы интерфейса, сравнительно ничто. Шиш.
После нормализации модели данных вы определяете компоненты как переменные, как свойства, как константы интерфейса контракта.
Затем вы определяете, что входит в введение значения, заполнение конфигурации свойств, интерфейсы, финальные строки и т. Д.
Если вы вынуждены использовать предлог для того, чтобы легче находить компонент, который можно диктовать для констант интерфейса, это означает, что у вас плохая привычка не практиковать нормализацию модели данных.
Возможно, вы хотите скомпилировать модель данных в выпуск vcs. Что вы можете вытащить четко идентифицируемую версию модели данных.
Значения, определенные в интерфейсах, гарантированно не изменяются. И поделился. Зачем загружать набор заключительных строк в ваш класс из другого класса, когда вам нужен только этот набор констант?
Так почему бы не опубликовать контракт модели данных? Я имею в виду, если вы можете согласованно и нормализовать это, то почему бы и нет? ...
Теперь я могу ссылаться на контрактные ярлыки моих приложений таким образом, как
Это смущает содержимое файла JAR? Как программист на Java, я не забочусь о структуре фляги.
Это представляет сложность для OSGI-мотивированного обмена времени выполнения? Osgi - чрезвычайно эффективное средство, позволяющее программистам продолжать вредные привычки. Есть лучшие альтернативы, чем osgi.
Или почему не это? Не существует утечки частных констант в опубликованный контракт. Все частные константы должны быть сгруппированы в закрытый интерфейс с именем «Константы», потому что я не хочу искать константы, и мне лень многократно набирать «private final String».
Возможно даже это:
Единственная проблема с интерфейсными константами, которую стоит рассмотреть, это когда интерфейс реализован.
Это не "оригинальное намерение" интерфейсов? Как будто меня заботит «первоначальное намерение» отцов-основателей при разработке Конституции США, а не то, как Верховный суд будет толковать письменные письма Конституции США ???
В конце концов, я живу в стране свободных, диких и дом храбрых. Будь смелым, будь свободным, будь диким - используй интерфейс. Если мои коллеги-программисты отказываются использовать эффективные и ленивые средства программирования, обязано ли я по золотому правилу снизить эффективность программирования, чтобы они соответствовали их? Возможно, я должен, но это не идеальная ситуация.
источник