0

This answer gives an indication that class String is declared final for thread safety, which does not convince.

This answer does not convince when it says: And so, you make the classes final. There can be no mutable String, because its an immutable class and its final.

Because,

below field with final modifier,

/** The value is used for character storage. */
    private final char value[];

in class String would suffice/indicate that data stored in the created object is suppose to be immutable and thread safe.

So, class String being final has nothing to do with immutability or thread safety.

But it is not clear, why class String is declared final?

Because, as per below class definition, it has final modifier:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{ .... }

So, class String cannot be inherited.

Despite field value[] in class String is declared final, additionaly, What is the necessity for class String also to be final?

Note: Answers to this question will give an idea behind this design decision

overexchange
  • 2,265
  • @gnat If declaring immutable class as final saves programmer from the need to repeat declaring final in each and every method declaration, then why required methods are declared final in public final class String{...}? – overexchange Jun 17 '15 at 08:10
  • to explicitly express an intent I guess. With over 60 methods in this class, it would be way too easy for reader to forget that whole class has been declared final somewhere far away from the point of method declaration. If it had one or two small methods, that could look superfluous... but String is nothing like that – gnat Jun 17 '15 at 08:15
  • ...and if you continue reading the link beyond ellipsis in quote, you'll find out that class level modifier also saves from accidentally omitting final in one of these 60+ methods, which is also important – gnat Jun 17 '15 at 08:21
  • @gnat accidentally? This is not an answer for above question. My question is not duplicate ): I need moderator attention. – overexchange Jun 17 '15 at 08:31
  • I wanna add something: there are reasons to have a final String-like class - however, why not just make a String interface and then an implementing ImmutableString class. So, everyone who cares for immutability e.g. for security or performance reasons can just expect its caller to deliver an ImmutableString. Everyone else can just accept a String. Why hasn't it been done this way? – valenterry Jun 17 '15 at 09:14
  • @valenterry After reading my question, when you say: there are reasons, please let me know, what are those? – overexchange Jun 17 '15 at 09:55
  • 1
    @overexchange e.g. if someone writes a method that accepts a String and he wants to make sure that he knows in before, how its methods are implemented. E.g. he wants to assure that "abc".startsWith("abc") is true and not false because someone has overwritten the method and is not passing a String but a CustomString class. – valenterry Jun 17 '15 at 10:46
  • @valenterry Every subclass of a class has to pass Liskov test, otherwise such problems would definitely occur. For example, a new subclass to a mutable super class(say) can behave as immutable. – overexchange Jun 17 '15 at 14:47
  • @overexchange Yes, you are totally right. But passing liskov test cannot be guaranteed by the compiler and therefore you want to have some way to make sure that a given type is passing this test for a specific type. The only way I can see to solve this is accepting only the specific type you know (and no subtype) so that you can be sure of the inner workings of that type. I hope we don't missunderstand each other here. – valenterry Jun 18 '15 at 14:34
  • @valenterry 1) How do we pass the Liskov test? I think like this.. If we consider implementationdetailPLUSinterface of a super class, the implementation part has to be designed in such a way that, if implementations of super class are changed in next release, it should not affect the public methods overridden in subclass. So, the barrier between interface and implementation should be well designed. 2) For your point: "liskov test cannot be guaranteed by the compiler" that is not at least my problem, If I have the code in my hand, I would refactor and make it right!!! – overexchange Jun 18 '15 at 14:46
  • @overexchange It's probably not your problem, but it's a problem for some people who want to make sure that their method always works, no matter what. So they decided to make String final to achieve this. Their mistake was probably not to make an interface for String. – valenterry Jun 18 '15 at 14:54