Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm a long time Java developer and finally, after majoring, I have time to study it decently in order to take the certification exam... One thing that has always bothered me is String being "final". I do understand it when a read about the security issues and related stuff... But, seriously, does anyone have a true example of that?

For instance, what would happen if String weren't final? Like it's not in Ruby. I haven't heard any complaints coming from the Ruby community... And I'm aware of the StringUtils and related classes that you have to either implement yourself or search over the web to just implement that behavior (4 lines of code) you're willing to.

share|improve this question
8  
You might be interested in this question on Stack Overflow: stackoverflow.com/questions/2068804/why-is-string-final-in-java –  Thomas Owens Jul 31 '11 at 20:16
    
Similarly, what would happen if java.io.File wasn't final. Oh, it isn't. Bugger. –  Tom Hawtin - tackline Nov 27 '12 at 18:09
add comment

4 Answers

up vote 15 down vote accepted

The main reason is speed: final classes can't be extended which allowed the JIT to do all kinds of optimizations when handling strings - there is never a need to check for overloaded methods.

Another reason is thread safety: Immutables are always thread safe because a thread has to completely build them before they can be passed to someone else - and after building, they can't be changed anymore.

Also, the inventors of the Java runtime always wanted to err on the side of safety. Being able to extend String (something I often do in Groovy because it's so convenient) can open a whole can of worms if you don't know what you're doing.

share|improve this answer
    
thanks. great answer. –  wleao Sep 3 '11 at 3:26
    
@JarrodRoberson: That is true. I believe the point is String itself is immutable and making it final ensures that anything that is a String is immutable, because to mutable subclass can be slipped in. –  back2dos Nov 8 '11 at 22:25
    
It's an incorrect answer. Other than for verification required by the JVM spec, HotSpot only uses final as a quick check that a method is not overridden when compiling code. –  Tom Hawtin - tackline Nov 27 '12 at 18:06
    
@TomHawtin-tackline: References? –  Aaron Digulla Nov 28 '12 at 8:28
add comment

There's another reason why Java's String class needs to be final: it is important for security in some scenarios. If the String class weren't final, the following code would be vulnerable to subtle attacks by a malicious caller:

 public String makeSafeLink(String url, String text) {
     if (!url.startsWith("http:") && !url.startsWith("https:"))
         throw SecurityException("only http/https URLs are allowed");
     return "<a href=\"" + escape(url) + "\">" + escape(text) + "</a>";
 }

The attack: a malicious caller could create a subclass of String, EvilString, where EvilString.startsWith() always returns true but where the value of EvilString is something evil (e.g., javascript:alert('xss')). Due to the subclassing, this would evade the security check. This attack is known as a time-of-check-to-time-of-use (TOCTTOU) vulnerability: between the time when the check is done (that the url starts with http/https) and the time when the value is used (to construct the html snippet), the effective value can change. If String wasn't final, then TOCTTOU risks would be pervasive.

So if String is not final, it becomes tricky to write secure code if you can't trust your caller. Of course, that's exactly the position that the Java libraries are in: they might be invoked by untrusted applets, so they don't dare trust their caller. This means that it would be unreasonably tricky to write secure library code, if String weren't final.

share|improve this answer
    
Of course, it's still possible to pull off that TOCTTOU vuln by using reflection to modify the char[] inside the string, but it requires some luck in the timing. –  Peter Taylor Nov 7 '11 at 8:27
1  
@Peter Taylor, it's more complicated than that. You can only use reflection to access private variables if the SecurityManager gives you permission to do so. Applets and other untrusted code are not given this permission, and thus cannot use reflection to modify the private char[] inside the string; therefore, they cannot exploit the TOCTTOU vulnerability. –  D.W. Nov 8 '11 at 8:10
    
I know, but that still leaves applications and signed applets - and how many people are actually scared off by the warning dialog for a self-signed applet? –  Peter Taylor Nov 8 '11 at 8:52
    
@Peter, that's not the point. The point is that writing trusted Java libraries would be a lot more difficult, and there would be a lot more reported vulnerabilities in Java libraries, if String wasn't final. As long as some of the time this threat model is relevant, then it becomes important to defend against. As long as it is important for applets and other untrusted code, that is arguably enough to justify making String final, even if it isn't needed for trusted applications. (In any case, trusted applications can already bypass all security measures, regardless whether it's final.) –  D.W. Nov 8 '11 at 21:47
add comment

If not, multithreaded java apps would be a mess (even worse than what actually is).

IMHO The primarily advantage of final strings (immutable) is that they are inherently thread-safe: they require no synchronization (writing that code is sometimes fairly trivial but more than less far from that). If the were mutable, guarantee things like multithreaded windows toolkits would be very hard, and those things are strictly necessary.

share|improve this answer
1  
final classes have nothing to do with mutability of the class. –  Jarrod Roberson Nov 8 '11 at 21:53
    
This answer does not addresses the question. -1 –  FUZxxl Nov 8 '11 at 22:08
2  
Jarrod Roberson: if the class was not final you could create mutable Strings using inheritance. –  ysdx Nov 8 '11 at 23:35
add comment

If String was not final, every programmer tool chest would contain its own "String with just a few nice helper methods". Each of these would be incompatible with all other tool chests.

I considered it to be a silly restriction. Today I am convinced this was a very sound decision. It keeps Strings to be Strings.

share|improve this answer
    
final in Java is not the same thing as final in C#. In this context, it is the same thing as C#'s readonly. See stackoverflow.com/questions/1327544/… –  MainMa Jul 31 '11 at 21:16
8  
@MainMa: Actually, in this context it seems that it's the same as C#'s sealed, as in public final class String. –  configurator Sep 2 '11 at 16:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.