Почему класс Wrapper, такой как Boolean в Java, является неизменным?
Я не вижу причины, по которой классы булевых оболочек стали неизменяемыми.
Почему Boolean Wrapper не был реализован как MutableBoolean в Commons lang, который на самом деле может быть сброшен.
У кого-нибудь есть идея / понимание по этому поводу? Благодарю.
4 ответа
Так как 2
2. Это не будет 3
завтра.
Immutable всегда предпочитается по умолчанию, особенно в многопоточных ситуациях, и это облегчает чтение и поддержку кода. Показательный пример: Java Date
API, который пронизан недостатками дизайна. Если Date
были бы неизменными API было бы очень упорядочено. я бы знал Date
Операции создадут новые даты и никогда не будут искать API, которые их изменяют.
Прочитайте параллелизм на практике, чтобы понять истинную важность неизменяемых типов.
Но также учтите, что если по какой-то причине вам нужны изменяемые типы, используйте AtomicInteger
AtomicBoolean
и т. д. Почему Atomic
? Потому что, вводя изменчивость, вы вводили необходимость в безопасности потоков. В чем бы вы не нуждались, если бы ваши типы оставались неизменными, поэтому при использовании изменяемых типов вы также должны заплатить за размышления о безопасности потоков и использование типов из concurrent
пакет. Добро пожаловать в удивительный мир параллельного программирования.
Также для Boolean
- Я призываю вас назвать одну операцию, которую вы, возможно, захотите выполнить, которая заботится о том, является ли Boolean изменяемым. установить в истину? использование myBool = true
, Это переназначение, а не мутация. Отрицание? myBool = !myBool
, То же правило. Обратите внимание, что неизменность - это функция, а не ограничение, поэтому, если вы можете предложить ее, вы должны - и в этих случаях, конечно, можете.
Обратите внимание, что это относится и к другим типам. Самая тонкая вещь с целыми числами count++
но это просто count = count + 1
, если вы не заботитесь о получении значения атомарно... в этом случае используйте изменяемый AtomicInteger
,
Классы Wrapper в Java являются неизменяемыми, поэтому среда выполнения может иметь только два логических объекта - один для true, другой для false - и каждая переменная является ссылкой на один из этих двух. И поскольку их никогда нельзя изменить, вы знаете, что их никогда не вытащат из-под вас. Это не только экономит память, но и упрощает анализ вашего кода - поскольку классы-обертки, которые вы знаете, никогда не изменят свое значение, они не будут внезапно переходить к новому значению, потому что они случайно ссылка на то же значение в другом месте.
Аналогично, Integer имеет кэш всех значений байтов со знаком - от -128 до 127 - поэтому среда выполнения не должна иметь дополнительных экземпляров этих общих значений Integer.
Паташу самый близкий. Многие из глупых вариантов дизайна в Java были из-за ограничений того, как они реализовали виртуальную машину. Я думаю, что первоначально они пытались создать виртуальную машину для C или C++, но это было слишком сложно (невозможно?), Поэтому сделал этот другой, похожий язык. Напиши один, беги везде! Любое оправдание компьютерного мышления, как и у других парней, носят просто послевоенный характер. Как вы теперь знаете, Java и C# развиваются так же мощно, как C. Конечно, они были чище. Должно быть для языков, разработанных десятилетия спустя! Простой трюк состоит в том, чтобы сделать класс "держателем". Или используйте закрытие в настоящее время! Возможно, Java развивается в JavaScript. ЛОЛ.
Логический или любой другой класс-обертка неизменен в Java. Поскольку классы-обертки используются в качестве переменных для хранения простых данных, они должны быть безопасными, а целостность данных должна поддерживаться во избежание противоречивых или нежелательных результатов. Кроме того, неизменность экономит много памяти, избегая дублирования объектов. Больше можно найти в статье Почему классы Strings & Wrapper созданы неизменяемым в Java?