What are Strings in Java?

Strings represent a sequence of characters. In Java, String is not a primitive data type like int or long, they are objects and the characters are stored internally as a char array.

The String class is used to represent strings and provides some methods that can be used to manipulate them and perform various operations.

How can you create Strings in Java?

The most common way to create a String is to use a literal like so:

String myString = "Hello World";

You will use this 99% of the time, but there can be cases when you would like to use one of the constructors of the String class (like when creating a String from a character array).

What is important to remember here is not to use this constructor:

new String("Hello World")

This will first create a new String from the literal that you specified (“Hello World”), it will then pass this to the constructor and that will create another String object with the same value. You have 2 objects instead of one, this is really inefficient.

How to check if two Strings are equal?

There are two ways to check for String equality.

The first way is to use the double equal sign (==). In most cases however this will not provide the expected result, because it will compare the references of the two Strings and those might not be the same. Two different String objects could exist with the same value, but their reference will not be the same.

The recommended way is to use the equals() method. It will work as expected because it will only compare the value of the two String objects.

Why there are classes like StringBuilder or StringBuffer?

Performing a lot of operations (like concatenation) on a String until you reach it’s final form can result in creating a lot of String objects, because each of these operations have the chance of creating a new object because of String’s immutability.

StringBuilder and StringBuffer helps in this situation by keeping track of the String you are building as a character array. It will only produce a String object when you are done with the building of the String and ask StringBuilder/StringBuffer to return the result.

After executing these lines we will have the following String objects:

4 String literals we see in the code.

1 extra String when we call toString().

As you can see in this example we have 5 instead of 7 strings. In more complex examples, the win would be even higher. For 1000 strings, it would be 1999 (without StringBuilder) vs 1001 (with StringBuilder).

When the substring() method was called, it just created a new String object that contained the same value, but used a different offset and count. As a result the new object referenced the old object and made it impossible for it to be garbage collected. If you had a lot of huge Strings, this wasted memory could add up to large amounts.

Here is the String constructor that causes the mentioned problem in JDK6.

In JDK7, this issue has been resolved. The String class no longer has the offset and count fields. When the substring() method is used, a new String is created by copying the required characters to a new object.

What is the static keyword for?

The static keyword means that a field or a method belongs to a class and not to an instance of the class. So it can be accessed without the need for an instance of it’s containing class.

Even if there are multiple instances of a class, the static fields will have only one instance shared between all of the class instances.

Can a class be static?

No, you can’t use the static keyword for a top-level class definition, it only has a meaning for members inside a class.

Think about it, what would it mean for a class to be static? In java, a static element means that you can access/invoke it without an instance of the enclosing class; what that could possibly mean if you apply the keyword to the class itself?

However, you can use the static keyword for inner classes. This way you can create an inner class that can have an instance without requiring an instance of the parent class.

What is a static inner class?

It is a class defined inside another class, using the static modifier. It is not tied to an instance of the outer class, you can reference it on it’s own even from outside of the class by prefixing it with the outer class’s name.

Of course, you can also create an instance of it inside the class. In that case, you do not need to use the Person prefix.

Can you override a static method?

No, you can not override a private method in Java, if you create a similar method with same return type and same method arguments in descendant class then it will hide the superclass method, this is known as method hiding.

Is there a way for a static method of a class to access an instance variable of an instance of the same class?

The first guess could be for many people that it is not possible. This is true in most cases, because inside a static method you are not inside an instance of the containing class.

However, your method can take parameters. If you can pass the instance that you need to access as a parameter, you will be able to access it’s fields and methods that are visible.

When are static fields initialized?

Static fields are initialized at the time of class loading in Java, opposite to instance variable which is initialized when you create instance of a particular class.

What is the initialization order of static fields?

Static fields are initialized based on the textual order they appear in the code.

What risks can you think of regarding static fields and parallel running?

In a concurrent environment you need to take extra care to ensure that static fields won’t get in an unwanted state because of multiple threads are modifying it at the same time.

Of course, this issue can be present with non static fields as well, but static fields can be more easily accessed from various parts of a program.

A great way to prevent this issue is to make them final, so their value cannot change.

What are the disadvantages of a static method in Java?

You cannot override a static method in Java. This makes testing harder as you can’t replace it with a mock.

However there are ways to overcome this limitation if you really want to mock some static methods: