С тех пор, как я узнал, что класс java.lang.String
объявлен как финальный в Java, мне стало интересно, почему это так. Тогда я не нашел никакого ответа, но этот пост: Как создать реплику класса String в Java? напомнил мне о моем запросе.
Конечно, String предоставляет всю необходимую мне функциональность, и я никогда не думал о какой-либо операции, которая потребовала бы расширения класса String, но, тем не менее, вы никогда не узнаете, что кому-то может понадобиться!
Итак, кто-нибудь знает, каково было намерение дизайнеров, когда они решили сделать его окончательным?
Спасибо за оба ответа. Я объединил оба ваших ответа в одно... свойство с таким фильтром:
def _get_blue_shirts(self):
if self.shirtclr.filter(shirtcolor='Blue'):
return '%s%s' % ('B', self.shirtmodel)
else:
return self.shirtmodel
blue_shirts=property(_get_blue_shirts)
Хотя этот подход определенно работает, я вижу проблемы с ним, как я написал его. Во-первых, я хотел бы найти в admin с, например, «B13A» в качестве модели рубашки и понять, что я имею в виду «13A» рубашка доступна с Blue в качестве одного из его цветов. Поскольку ModelAdmin.search_fields, по-видимому, необходимо перейти к фактическому полю, этот подход не работает в этом отношении (исправьте меня, если я там не прав). Другая проблема, которую я имею, заключается в том, что свойство кажется очень тяжелым для SQL... выполнение отдельного выбора для каждой строки (в то время как выделенному столбцу просто нужен общий выбор... снова, исправьте меня, если я не прав). Есть идеи, как я могу решить эти проблемы? Возможно, я мог бы пойти по этому пути?
PS. Энтони... Я попробовал переработанный переопределенный save () и все еще получил экземпляр "" ShirtClass "" должен иметь значение первичного ключа, прежде чем отношение "многие ко многим" может быть использовано "ошибка. Я делаю что-то не так здесь?
Многие, многие, большое спасибо всем, -bkev
-121--4196174-Это не должно занять столько времени.
Одно дело - очистить список последних файлов.
ALT + x recentf-cleanup
Другое дело, чтобы убедиться, что ваш файл .emacs только что скомпилирован, если вы изменили даже один или два символа, то Emacs увидит, что ваш файл .emacs новее скомпилированной версии и он не будет использовать скомпилированную версию.
Выполните следующее:
ALT + x byte-compile-file
Затем перейдите к файлу .emacs и нажмите Enter, чтобы создать файл с именем .emacs.elc
Emacs будет использовать .emacs.elc, если он не старше вашего файла .emacs
-121--3926492-Очень полезно иметь последовательности, реализованные как неизменяемые объекты . Вы должны прочитать о неизменяемости , чтобы понять больше об этом.
Одно из преимуществ неизменяемых объектов состоит в том, что
дубликаты можно совместно использовать, указывая их на один экземпляр.
(от здесь ).
Если последовательность не были окончательными, можно создать подкласс и иметь два ряды, похожие на «видимые как последовательности», но фактически отличающиеся друг от друга.
String
- это очень основной класс в Java, многие вещи полагаются на него, работают определенным образом, например, неизменным.
Создание класса Final
предотвращает подклассы, которые могут нарушить эти предположения.
Обратите внимание, что даже сейчас, если вы используете отражение , вы можете сломать строки (измените их значение или hashcode). Отражение может быть остановлено с помощью менеджера безопасности. Если строка
не было финала
, каждый мог это сделать.
Другие классы, которые не объявлены Финал
позволяют определить несколько сломанные подклассы (вы могли бы иметь список
, который добавляет к неправильному положению, например), но, по крайней мере, JVM не зависит от тех, которые для его основных операций.
Возможно, это было упростить реализацию. Если вы разработаете класс, который будет наследственным пользователям класса, то у вас есть совершенно новый набор случаев использования, чтобы учитывать ваш дизайн. Что произойдет, если они сделают это или что с X предпринимаемым полем? Делать его окончательным, они могут сосредоточиться на правильной работе общедоступного интерфейса, и убедитесь, что это твердое.
Это хорошая статья , которая описывает две причины, уже упомянутые в ответах на вышеприведенные вопросы:
И это, пожалуй, самый подробный комментарий в этой статье. Он касается пула строк в Java и вопросов безопасности. Он о том, как решить, что попадает в строковый пул. Если предположить, что обе строки равны, если их последовательность символов одинакова, то у нас есть условие гонки на то, кто попадет туда первым, и вместе с этим проблемы безопасности. Если нет, то пул строк будет содержать лишние строки, теряя тем самым преимущество. Просто прочитайте это для себя, ладно?
Расширение струн будет играть хаос с равными и интернами. JavaDoc говорит equals:
Сравнивает эту строку с указанным объектом. Результат верен, если и только если аргумент не равен нулю и является объектом String, который представляет ту же самую последовательность символов, что и объект this.
Если предположить, что java.lang.String
не является окончательным, то SafeString
может быть равен String
, и наоборот; потому что они будут представлять ту же самую последовательность символов.
Что произойдет, если применить intern
к SafeString
-- пойдет ли SafeString
в пул строк JVM? КлассLoader ClassLoader
и все объекты, на которые ссылается SafeString
, будут заблокированы на время жизни JVM. Вы получите состояние гонки о том, кто может первым вставить последовательность символов -- может быть ваш SafeString
выиграет, может быть String
, или может быть SafeString
загруженный другим классом загрузчика (таким образом другим классом).
Если бы вы выиграли гонку в пул, это был бы настоящий singleton, и люди могли бы получить доступ ко всему окружению (песочнице) через отражение и secretKey.intern().getClass().getClassLoader()
.
Или JVM мог заблокировать эту дыру, убедившись, что в пул были добавлены только конкретные объекты String (и никаких подклассов).
Если бы равные были реализованы так, что SafeString
!= String
, то SafeString.intern
!= String.intern
, и SafeString
должны были бы быть добавлены в пул. Затем пул станет пулом
вместо
, и все, что вам нужно, чтобы войти в пул, будет свежим загрузчиком классов.
Как сказал Бруно, это о неизменности. Это не только о струнах, но и о любых обертках E.g. Двойной, целочисленные, характер и т. Д. Есть много причин для этого:
в основном это, так что вы, как программист, могут быть уверены, что ваша строка никогда не будет изменена. Это также, если вы знаете, как это работает, может улучшить менеджер памяти. Попробуйте создать две идентичные строки один за другим, например, «Hello». Вы заметите, если вы отладки, что у них есть идентичные идентификаторы, это означает, что они точно такие же объекты. Это связано с тем, что Java давайте сделаем это. Это не было бы возможно, если струны были исправлены. Они могут иметь то же самое, что я и т. Д., потому что они никогда не изменится. Поэтому, если вы когда-нибудь решите создать 1 000 000 строк «Hello», что вы действительно сделаете, это создать 1 000 000 указателей на «Hello». Помимо любая функция на строке или любые обертки по этой причине, приведет к созданию другого объекта (снова посмотрите на идентификатор объекта - он изменится).
Плитингово финал в Java не обязательно не обязательно означает, что объект не может измениться (он отличается для примера C ++). Это означает, что адрес, к которому он точки не может измениться, но вы все равно можете изменить его свойства и / или атрибуты. Поэтому понимание разницы между неизменностью и финалом в некоторых случаях может быть действительно важным.
HTH
Список литературы:
В дополнение к причинам, указанным в других ответах (безопасность, неизменяемость, производительность), следует отметить, что String
имеет специальную языковую поддержку. Вы можете писать литералы String
, и есть поддержка оператора +
. Разрешение программистам создавать подклассы String
будет способствовать взлому, например:
class MyComplex extends String { ... }
MyComplex a = new MyComplex("5+3i");
MyComplex b = new MyComplex("7+4i");
MyComplex c = new MyComplex(a + b); // would work since a and b are strings,
// and a string + a string is a string.