Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

5 Facts about the Java String

3.96/5 (6 votes)
11 Dec 2013CPOL5 min read 33.5K  
Discover some interesting facts about the Java String

Introduction

String is one of the fundamentals of Java programming language. It's not a primitive data type like int, long or double. It's defined in java.lang package and wrappers its content in a character array.

In this post, we will discover some interesting String facts, that could help in understanding better the behavior of this popular class.

1. String is Immutable

There is a powerful and simple concept in programming that is really underused: Immutability.

Basically, an object is immutable if its state doesn’t change once the object has been created. Consequently, a class is immutable if its instances are immutable.

There is one killer argument for using immutable objects: It dramatically simplifies concurrent programming. Think about it, why is writing proper multithreaded programming a hard task? Because it is hard to synchronize thread accesses to resources (objects or others OS things). Why it is hard to synchronize these accesses? Because it is hard to guarantee that there won’t be race conditions between the multiple write accesses and read accesses done by multiple threads on multiple objects. What if there are no more write accesses? In other words, what if the state of the objects threads are accessing, doesn’t change? There is no more need for synchronization!

Immutable classes are also well adapted to be key in hashtables. The objects on which the hash values are computed must be immutable to make sure that the hash values will be constant in time. Indeed, hash value is computed from the state of the object.

String is immutable. When you think that you are modifying a string, you actually create a new string object. Often, we forget about it and we would like to write …

Java
String str = "foofoo";

str.replace("foo", "FOO"); 

…where we need to write instead:

Java
str = str.replace("foo", "FOO"); 

Of course, doing so comes at the cost of creating multiple string objects in memory when doing some intensive string computation. In this case, you need to use the StringBuilder class.

For some modern languages like Scala, immutability is preferred. The default collection classes are immutable.

2. String is the Most Popular Class in the JVM

It’s interesting to know the most used types in a project, indeed these types must be well designed, implemented and tested. And any change to them could impact the whole project.

Let’s analyse the JVM with JArchitect and search for its most popular types. For that, we can use two metrics:

Type Afferent Coupling (TypeCa): which is the number of types using a specific class. And here’s the result of all popular types according to this metric:

Image 1

As expected, Object is the most used one, however there's another interesting metric to search for popular types: TypeRank.

TypeRank values are computed by applying the Google PageRank algorithm on the graph of types’ dependencies. A homothety of center 0.15 is applied to make it so that the average of TypeRank is 1.

Types with high TypeRank should be more carefully tested because bugs in such types will likely be more catastrophic.

Here’s the result of all popular types according to the TypeRank metric:

Image 2

Using TypeRank metric which is more accurate to search for popular types, String is more popular than Object in the JVM codebase.

3. String is Stable

It’s recommended that the most popular code elements must be stable, indeed any changes could impact many other types, let’s discover if it’s the case of String, for that we can compare the JVM 5 released in September 30, 2004 and the last update of JVM 7 released in October 15, 2013.

Added Methods

Here are the methods added during 9 years:

Image 3

Only 3 constructors and 5 methods was added.

Deprecated Methods

Image 4

Only one constructor was deprecated since 2004.

4. String is Designed to Optimise the Memory Usage

Strings receive special treatment in Java, because they are used frequently in a program. Hence, efficiency (in terms of computation and storage) is crucial.

There are two ways to construct a string: implicit construction by assigning a string literal or explicitly creating a String object via the new operator and constructor. For example:

Java
String s1 = "Hello"; // String literal 
Java
String s2 = new String("Hello"); // String object 

Java has provided a special mechanism for keeping the String literals – in a so-called string common pool. If two string literals have the same contents, they will share the same storage inside the common pool. This approach is adopted to conserve storage for frequently-used strings. On the other hand, String objects created via the new operator and constructor are kept in the heap. Each String object in the heap has its own storage just like any other object. There is no sharing of storage in heap even if two String objects have the same contents.

You can refer to this post for more details about the String pool mechanism.

5. String is Designed to Optimise the CPU Usage

We can enumerate two cases of CPU optimisation:

  • Execute minimal of code whenever it's possible:
    Let’s take as example the toLowerCase(Locale locale) method, and here are the first lines of its implementation:
    Java
    public String toLowerCase(Locale locale) {
    if (locale == null) {
        throw new NullPointerException();
    }
    ……

    locale is used early in the method body, the JVM throws the NullPointerException if a pointer is null and it’s very uncommon to throw explicitly this exception. However many methods from String use this technique to avoid executing more code in case of abnormal cases, which could minimize the CPU usage.

  • isEmpty instead of equals(“”): isEmpty was introduced in Java 6 which is faster than equals(“”), because it simply compares the length of the string – which is stored in the String object – with zero:
    Java
    public boolean isEmpty() {
    return 0 == count;
    } 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)