Почему класс String является окончательным?

Возможный дубликат:
Почему String final в Java?

В моей жизни программирования были разные моменты, когда я хотел, чтобы класс String не был окончательным/запечатанным/NotInheritable.

Какие языковые архитекторы пытаются помешать мне сделать, что может поставить под угрозу работу.

Скорее, какие гаечные ключи архитекторы языка хотели бы помешать мне использовать в работе, ограничивая меня в расширении класса String?

Не могли бы вы перечислить список плюсов и минусов класса расширяемой строки?


person Blessed Geek    schedule 02.08.2010    source источник
comment
Я понимаю, что есть и другие классы, такие как числовые, которые также закрыты. Мы могли бы начать с анализа String, но ваши комментарии не должны ограничиваться String.   -  person Blessed Geek    schedule 02.08.2010
comment
+1... Я тоже хотел когда-то в жизни расширить класс String, правда не помню зачем   -  person    schedule 02.08.2010
comment
Как вы упомянули java (тег), об этом уже спрашивали: stackoverflow.com/questions/2068804/why-is-string-final-in-java   -  person Kevin Brock    schedule 02.08.2010
comment
это точная копия stackoverflow.com/ вопросы/2068804/почему-строка-финал-в-java   -  person hvgotcodes    schedule 02.08.2010
comment
Отклонено, потому что: дубликат уже отвеченного вопроса .com/questions/2068804/why-is-string-final-in-java   -  person Alain O'Dea    schedule 02.08.2010


Ответы (2)


Строка является неизменяемым классом, что означает, что вы не можете изменить ее состояние после ее создания. Если бы вы могли изменить строку после того, как она попала в другую библиотеку или, например, карту, результат был бы непредсказуемым.

Одна ошибка Java API заключается в том, что BigInteger< /a> и BigDecimal не являются окончательными, что означает, что вам необходимо выполнять защитную копию этих объектов при их получении из недоверенного кода. И наоборот, вы всегда можете быть уверены, что String останется согласованным.

Ненадежный BigInteger:

public class DestructiveBigInteger extends BigInteger {

    public DestructiveBigInteger(String value) {
        super(value);
    }

    public BigInteger add(BigInteger val) {
        return BigInteger.ONE; // add() method does not behave correctly
    }

    public BigInteger subtract(BigInteger val) {
        throw new UnsupportedOperationException("subtract is broken");
    }
}

То же самое невозможно с String. Как указано в Effective Java, вам необходимо создавать защитные копии этих типов объектов. :

public void setValue(BigInteger value) {
    this.value = new BigInteger(value.toByteArray());
}
person krock    schedule 02.08.2010
comment
Убедитесь, что вы знаете разницу между ключевым словом final и ключевым словом sealed. Классы, помеченные как final, ТАКЖЕ эффективно запечатаны, но суть ключевого слова final не в этом. Класс final является неизменяемым, то есть его нельзя изменить после создания. Неизменяемые классы также должны быть запечатаны, иначе можно было бы наследовать, переопределять и добавлять какое-то неизменяемое поведение. Строки неизменяемы в Java, потому что изменяемые строки опасны и, откровенно говоря, доставляют больше проблем, чем пользы. Большинство современных языков (Python, Javascript, C#, Java) используют неизменяемые строки. - person Ender; 02.08.2010

String является окончательным, поскольку представляет неизменяемый тип данных. В результате наивного расширения String возникнет многообразие ужасов, потому что существует множество библиотек, зависящих от неизменности объектов String.

Расширение String, чтобы сделать его изменяемым, будет невидимым для любого кода, через который проходит Sting, но будет иметь очень неожиданные и неприятные побочные эффекты, такие как внезапная невозможность загрузки значений из HashMaps, даже если у вас буквально есть String ключа, поскольку hashCode был бы угнан.

person Alain O'Dea    schedule 02.08.2010
comment
Если бы я хотел использовать String для ключей карты, я бы использовал String. Если бы я хотел использовать расширенную строку в качестве ключа к карте, это именно то, что я хочу сделать - предотвратить доступ к ней с помощью базовых объектов String. Аргумент неизменности, кажется, не выдерживает критики для меня. - person Blessed Geek; 02.08.2010
comment
Но расширенная строка была бы строкой. Таким образом, вы можете использовать его как ключ карты из String. Отсутствие возможности наследования не мешает вам написать класс, расширяющий возможности String (используя композицию). Это просто мешает вам превращать экземпляры этого класса в строки. - person jwg; 02.08.2013