Question 2: Is a String mutable?
- How is a String stored in memory?
- What are the differences between a String in Java and a String in C?
- In Java, what is the difference between the String Class and the StringBuilder Class?
What They’re Actually Asking
- Do you know how objects are stored in memory? Do you understand different segments of memory?
- This question has different answers for a Java String, a C String, and a shoestring. If a question is unclear, will you ask a follow-up question?
- Do you evaluate the tradeoffs between different classes when developing code? Do you understand the tradeoffs between the String class and the StringBuilder class?
Tools for the Answer
- A String is a finite sequence of characters usually stored as an array of characters with a terminating value. These characters are usually letters, numbers, punctuation, etc.
- In computer science, a mutable object can be changed after it’s created. In our context, a String is mutable if it is created as “Hello” and can be changed to “Zello” (or any other change).
- When we create a variable in our code, the variable must be stored at some location in memory. The storage locations will vary based on compiler and language. But, at a high level, we can think of data as being stored in two locations: a read-only location or a read-write location. For those interested in learning more about how C stores variables, see here.
- When creating a String in C, we have a few options. The options below all create Strings that are mutable. This is because these Strings are stored in the stack segment or the heap segment. Both of these locations are read-write locations in memory. This means we can change characters in our String as we see fit. The ‘ ’ character is a null terminator that represents the end of the String.
- There is one other way to create a String in C, shown below. This String will not be mutable. This String is (most-likely) stored in a read-only block of memory in the data segment. If you try to change this String, you’ll get a segfault.
- Strings in Java are created as objects of the java.lang.String class. There are two main ways to create Strings in Java, shown below.
- Strings in Java are stored in the heap. So, as we saw with Strings in C, we should be able to change values in a String. However, these objects are instantiations of the String class so the only way we could change them is by using the String class. This stems from the Object Oriented Principle of encapsulation.
- All of the methods for a Java String Object can be found here but I’ll save you the read — no method exists to update a String value once it has been created. This makes String Objects immutable.
- A clever workaround would be to override a method in this String Class and create a method that allows you to update values. Then, this String Object would technically be mutable. However, the String Class is a final class. A final class cannot be extended (i.e. cannot be a parent class) and all methods in this class are final. A final method cannot be overridden.
- However, Java does have a Class that implements a mutable String Object. This is the java.lang.StringBuilder Class. There is heavy overlap in terms of methods for both classes. The key difference is any operation (e.g. concatenation) performed on a String object creates and returns a new object. This same operation performed on a StringBuilder object would update the original object.
- The runtime of a StringBuilder object outperforms a String object for multiple operations. This is because a String object needs to create and copy additional objects from memory every time. Also, String and StringBuilder are not thread safe. We cover the concepts of synchronization and thread safety in Part 2.
- For those interested, the StringBuffer class is a threadsafe option that functions similarly to a StringBuilder object.
Well, it depends. If we are talking about a String in C, most of the time, yes it is mutable. This is because Strings in C are stored as character arrays. As long as they are stored in a memory location to which you can read and write, you can change their values, making them mutable. However, if a String is assigned to a pointer directly, then it will likely be stored in a read-only block of memory in the data segment. In this situation, the String would not be mutable.
If we are working in Java, a String is an instantiation of the String Class. These values are stored in a memory location where we can write. However, the String Class does not provide any methods for updating the value of a String after it has been created. Since this is is a final class, we cannot override any of these methods. This means a String in Java is not mutable.
However, Java does provide the StringBuilder Class. This Class is very similar to the String Class except it represents Strings as a mutable character array. If our code runs operations on a StringBuilder Object, the original StringBuilder object is updated. For operations on a String, a new String Object would be created for each operation.
This question was mainly answered through the lens of Java and C, as they provide a good framework for explanation. However, this thought process can be applied to other languages. As long as you understand where and how the variables are stored, the question of mutability answers itself.
One huge takeaway from this question is to ask questions! As we’ve seen, this question has different answers for a String in C or a String in Java. Your interviewer may want to know about a String in Python or a String as an abstract concept (independent of a specific language). It is always best practice to clarify before giving an answer.