Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the String class declared final in Java?

Tags:

java

string

final

People also ask

Why String class is final or immutable?

The string is immutable means that we cannot change the object itself, but we can change the reference to the object. The string is made final to not allow others to extend it and destroy its immutability.

Can String declared as a final?

In Java, we know that String objects are immutable means we can't change anything to the existing String objects. final means that you can't change the object's reference to point to another reference or another object, but you can still mutate its state (using setter methods e.g).

Why the String is immutable?

Being immutable automatically makes the String thread safe since they won't be changed when accessed from multiple threads. Hence immutable objects, in general, can be shared across multiple threads running simultaneously.

Why String is immutable with example?

In the String constant pool, a String object is likely to have one or many references. If several references point to the same String without even knowing it, it would be bad if one of the references modified that String value. That's why String objects are immutable.


It is very useful to have strings implemented as immutable objects. You should read about immutability to understand more about it.

One advantage of immutable objects is that

You can share duplicates by pointing them to a single instance.

(from here).

If String were not final, you could create a subclass and have two strings that look alike when "seen as Strings", but that are actually different.


This is a nice article that outlines two reasons already mentioned on the above answers:

  1. Security: the system can hand out sensitive bits of read-only information without worrying that they will be altered
  2. Performance: immutable data is very useful in making things thread-safe.

And this probably is the most detailed comment in that article. Its has to do with the string pool in Java and security issues. Its about how to decide what goes into the string pool. Assuming both strings are equal if their sequence of characters are the same, then we have a race condition on who gets there first and along with it security issues. If not, then the string pool will contain redundant strings thus losing the advantage of having it in the first place. Just read it out for yourself, will ya?


Extending String would play havoc with equals and intern. JavaDoc says equals:

Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.

Assuming java.lang.String wasn't final, a SafeString could equal a String, and vice versa; because they'd represent the same sequence of characters.

What would happen if you applied intern to a SafeString -- would the SafeString go into the JVM's string pool? The ClassLoader and all objects the SafeString held references to would then get locked in place for the lifetime of the JVM. You'd get a race condition about who could be the first to intern a sequence of characters -- maybe your SafeString would win, maybe a String, or maybe a SafeString loaded by a different classloader (thus a different class).

If you won the race into the pool, this would be a true singleton and people could access your whole environment (sandbox) through reflection and secretKey.intern().getClass().getClassLoader().

Or the JVM could block this hole by making sure that only concrete String objects (and no subclasses) were added to the pool.

If equals was implemented such that SafeString != String then SafeString.intern != String.intern, and SafeString would have to be added to the pool. The pool would then become a pool of <Class, String> instead of <String> and all you'd need to enter the pool would be a fresh classloader.


The absolutely most important reason that String is immutable or final is that it is used by the class loading mechanism, and thus have profound and fundamental security aspects.

Had String been mutable or not final, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter"

reference : Why String is immutable in Java


String is a very core class in Java, many things rely on it working a certain way, for example being immutable.

Making the class final prevents subclasses that could break these assumptions.

Note that, even now, if you use reflection, you can break Strings (change their value or hashcode). Reflection can be stopped with a security manager. If String was not final, everyone could do it.

Other classes that are not declared final allow you to define somewhat broken subclasses (you could have a List that adds to the wrong position, for example) but at least the JVM does not depend on those for its core operations.


As Bruno said it's about immutability. It's not only about Strings but as well about any wrappers e.g. Double, Integer, Character, etc. There are many reasons for this:

  • Thread safety
  • Security
  • Heap that is managed by Java itself (differently to ordinary heap that is Garbage Collected in different manner)
  • Memory management

Basically it so you, as a programmer, can be sure that your string will never be changed. It as well, if you know how it works, can improve memory managemnt. Try to create two identical string one after another, for example "hello". You will notice, if you debug, that they have identical IDs, that means that they are exactly THE SAME objects. This is due to the fact that Java let's you do it. This wouldn't be posssible if the strings were muttable. They can have the same I'd, etc., because they will never change. So if you ever decide to create 1,000,000 string "hello" what you'd really do is create 1,000,000 pointers to "hello". As well alling any function on string, or any wrappers for that reason, would result in creating another object (again look at object ID - it will change).

Aditionally final in Java does not necessarily mean that object cannot change (it is different to for example C++). It means that the address to which it points cannot change, but you still can change it's properties and/or attributes. So understanding the difference between immutability and final in some case might be really important.

HTH

References:

  • http://chaoticjava.com/posts/how-does-garbage-collection-work/
  • http://chaoticjava.com/posts/gc-tips-and-memory-leaks/
  • http://java.sun.com/j2se/1.5/pdf/jdk50_ts_guide.pdf