Why String is immutable or final in Java [duplicate] - java

This question already has answers here:
Why is the String class declared final in Java?
(16 answers)
Closed 9 years ago.
As i was told this is important String Interview question in Java, which starts with discussion of " What is String ", how String is different in java than in C or C++ and then you are asked about immutable objects and you're asked the main question: " Why String is immutable or final in Java ".
Can you share your Ideas ?
Thanks in advance.

It is mainly for security reasons. String is used as parameter in network connection, database url etc. It can be easily attacked if it is mutable
Immutability of String solves some synchronization issues, it makes the String thread safe
To support StringPool facility
To cache the hashcode of String
To support class loading mechanism in which String is used as arguments. String being mutable results in wrong class being loaded

The two main reasons why strings are immutable in many modern languages, including Java, are security and performance (or, more precisely, chance for optimizations).
The fact that strings are final is to ensure their immutability (by forbidding anyone from extending them and making them mutable again).

The most important reason is security.
A lot of security risks would appear if a malicious thread could gain a reference to a mutable String, which is about to be passed into a method that has to validate the String before it performs an important operation. It would be possible for the thread to change the string after it was validated, and then the operation would be carried out using a dangerous String.
Another reason of Why String is immutable in Java is to allow String to cache its hashcode
As mentioned above - the most important reason - security & thread safety.
Consider a scenario, in a banking application for money transfer - the beneficiary account number is defined in a string as "0789567345".
If by mistake/intentionally this acc. number is changed, money will go to a wrong account.
Another scenario - if someone change the class name anywhere between processing as ..
getClass().getName().subString(0, 5);
The Class loader will simply say 'Class Not Found

Related

Why String being final makes application more safe?

For some time, I am trying to understand how String works, and I do not understand the aspect of security.
"In case, if String is not immutable, this would lead serious security threat, I mean someone can access to any file for which he has authorization, and then can change the file name either deliberately or accidentally and gain access to that file. Because of immutability, you don't need to worry about that kind of threats. This reason also gels with, Why String is final in Java, by making java.lang.String final, Java designer ensured that no one overrides any behavior of String class."
https://javarevisited.blogspot.com/2010/10/why-string-is-immutable-or-final-in-java.html
String is immutable, so new object is created when we try to edit and a variable of type String has a new reference. If we can swap references, how is it safe? Someone could do just that and still get access to something he is not authorized to. Or maybe I do not understand this correctly?
Edit: Maybe I should rephrase my question. If String was mutable, how could security threat look like? Someone could access String pool and change the value there and in that way and for example unauthorized access to some file could be granted?
The final keyword provides a recommendation.
The String class is not labeled final to make the program more safe. It is labeled this way because it is a core language feature and so that programmers don't try to edit it. Editing it or extending functionality can change how this core feature works, and make the program behavior unpredictable, since the language depends on the String class being programmed the way it comes originally.
Any class can actually be modified if someone insists on doing so using Reflection. However, it isn't possible to extend a final class.
In terms of security, there is no built-in security for your Java programs. Security such as handling what third party code can access your Java code or program memory is handled by the operating system.

How does the JVM lookup the String in the String constant pool? [duplicate]

This question already has answers here:
What is the Java string pool and how is "s" different from new String("s")? [duplicate]
(5 answers)
Closed 7 years ago.
I want to understand the string pool more deeply. Please help me get to the source class file containing this implementation in Java.
The question is more of related to finding the source code or implementation of the String Pool to delve deeper on this concept to know more about some unknown or elusive things in it. This way we can make the use of strings even more efficiently or think of some other way to implement our own garbage collections in case we have an application creating so many literals and string objects.
I am sorry to disappoint you but the Java String-Pool is not an actual Java class but somewhere implemented in the JVM i.e. it is writen as C++ code.
If you look at the source code of the String class (pretty much all the way down) you see that the intern() method is native.
You will have to go through some JVM code to get more information.
Edit:
Some implementation can be found here (C++ header, C++ implementation). Search for StringTable.
Edit2: As Holger pointed out in the comments, this is not a hard requirement of the JVM implementation. So it is possible to have a JVM that implements the String Pool differently, e.g. using an actual Java class. Though all commonly used JVMs I am aware of implement it in the JVMs C++ code.
You can go through this article: Strings, Literally
When a .java file is compiled into a .class file, any String literals
are noted in a special way, just as all constants are. When a class is
loaded (note that loading happens prior to initialization), the JVM
goes through the code for the class and looks for String literals.
When it finds one, it checks to see if an equivalent String is already
referenced from the heap. If not, it creates a String instance on the
heap and stores a reference to that object in the constant table. Once
a reference is made to that String object, any references to that
String literal throughout your program are simply replaced with the
reference to the object referenced from the String Literal Pool.
So, in the example shown above, there would be only one entry in the
String Literal Pool, which would refer to a String object that
contained the word "someString". Both of the local variables, one and
two, would be assigned a reference to that single String object. You
can see that this is true by looking at the output of the above
program. While the equals() method checks to see if the String objects
contain the same data ("someString"), the == operator, when used on
objects, checks for referential equality - that means that it will
return true if and only if the two reference variables refer to the
exact same object. In such a case, the references are equal. From the
above output, you can see that the local variables, one and two, not
only refer to Strings that contain the same data, they refer to the
same object.

Programming practice for defining string constants in Java

My perception for defining string constants in Java is that one should define a string constant, when the same string is used at multiple places. This help in reducing typo errors, reduce the effort for future changes to the string etc.
But how about string that are used at a single place. Should we declare string constant even in that case.
For eg. Logging Some counter (random example).
CounterLogger.addCounter("Method.Requested" , 1)
Is there an advantage of declaring constant rather than using raw string?
Does the compiler does any optimization?
Declaring constants can improve your code because they can be more descriptive. In your example
CounterLogger.addCounter("Method.Requested" , 1)
The method parameter "Method.Requested" is quite self describing but the 1 is not making this a constant would make this example more readable.
CounterLogger.addCounter("Method.Requested" , INITIAL_VALUE)
The way I see it, Strings can be used in one of two ways:
As properties / keys / enumerations - or in other words, as an internal representation of another Objects/states of your application, where one code component writes them, and another one reads them.
In UI - for GUI / console / logging display purposes.
I Think it's easy to see how in both cases it's important to avoid hard-coding.
The first kind of strings must (if possible) be stored as constants and exposed to whichever program component that might use them for input/output.
Displayed Strings (like in your Logger case) are strings that you might change somewhere in the future. Having them all stored as static final fields in a constants-dedicated class can make later modifications much easier, and help avoid duplicates of similar massages.
Regarding the optimization question - as others have already answered, I believe there's no significant difference.
Presumably, you'll want to write a unit test for whichever method contains that line of code. That unit test will need access to that String value. If you don't use a constant, you'll have the String repeated twice, and if you have to change it in the future, you'll have to change it in both places.
So best to use a constant, even though the compiler is not going to do any helpful optimisations.
In my view in your case is fine. If you cant see any advantage in declaring it as a constant dont do it. To support this point take a look at Spring JdbcTemplate (I have no doubt that Spring code is a good example to follow) it is full of String literals like these
Assert.notNull(psc, "PreparedStatementCreator must not be null");
Assert.notNull(action, "Callback object must not be null");
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
but only two constants
private static final String RETURN_RESULT_SET_PREFIX = "#result-set-";
private static final String RETURN_UPDATE_COUNT_PREFIX = "#update-count-";
Iterestingly, this line
Assert.notNull(sql, "SQL must not be null");
repeats 5 times in the code nevertheless the authors refused to make it a constant

String immutability and wait method in synchronized block [duplicate]

This question already has answers here:
Why is the String class declared final in Java?
(16 answers)
Closed 9 years ago.
I am new to Java and while I was reading through Java language I got into two doubts. Though I referred many websites and but still I am not very clear.
Why string class is immutable ? I saw some examples with new File(str) which leads to security threat, but I don't understand how if string is immutable, it will help this scenario.
Another doubt is why wait, notify and notifyall should be inside synchronized block. I know if not it throws illegalMonitorException. But I want to know the technical background why it should be in synchronized block and why not without in synchronized block wait and notify can have same behavior.
Why string class is immutable?
The question of why strings are immutable in Java is an old one, and it's been much debated. In my book, I'd say they are immutable because they should be immutable ;). That might sound like a cop out, but let me explain.
Most simply, strings are used all over the place, if they were mutable that would require a lot of baggage everywhere for making defensive copies and dealing with synchronization and so on. Making them immutable, and then having helpers for mutating them like StringBuilder/StringBuffer is a much better design choice (and a common choice in several languages, not just Java).
Second, everything should be immutable, unless there is a very good reason to justify mutability. Many many problems disappear with immutable classes (esp. pertaining to concurrency). See Effective Java: "Classes should be immutable unless there's a very good reason to make them mutable. If a class cannot be made immutable, limit its mutability as much as possible."
Third, strings are used in the internals of Java, such as the class loading mechanism. Making them immutable makes internal processes simpler, and prevents some security issues. (Another example, String constants are "interned" in Java for performance reasons: http://en.wikipedia.org/wiki/String_interning, and this is, again, much more sane with an immutable type.)
All in all there were probably several reasons the designers chose to make strings immutable in Java and as a day to day programmer it helps you out (as do the utils around creating new strings, like StringBuilder).
Why wait, notify and notifyall should be inside synchronized block?
Here's some info on that one: wait(), notify() and notifyAll() inside synchronized statement.
Basically it makes no sense for a thread to "notify" or "wait" unless it already owns the object's monitor.
In general though, if you are new to Java, you might want to also look at some of the newer utils relating to concurrency in java.util.concurrent: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html. Often you can rely on these classes and avoid hand coding synchronization, which is notoriously difficult and error prone.

Why is String final? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why is String final in Java?
I'm just wondering why java.lang.String is made final? Is it to prevent from being inherited? Why?
Yes indeed. This allows code in security managers and classloaders to work with the String type without having to worry that it's actually dealing with a malicious subclass that's specifically designed to trick it into allowing evil code through.
You should not be extending the string class. Just write your own methods in some other class that manipulate strings.
The reason is that the string class is a stable one which should not be tampered with as you may re-define some methods which would have unknown side effects on some other transactions.
Aside from security aspects that were already mentioned, I suspect performance was another important reason. For older JVMs especially final classes (where all methods are final by definition) made it much easier to inline code on-the-fly. And since String is one of most heavily used objects, which affects overall performance of many applications, this was seen as an area where improvements would have big overall effect.

Categories