Taste of String

String is always a popular topic in java. Beyond all question String is an object type. But sometimes it seems like a basic data type. Many website emphasize we should identify between one situation when we use String a = “abc” and the other when String a = new String(“abc”).

Why I say String sometimes looks like a basic data type. Let’s see a simple example first:

public class Test {
	public static void main(String[] args) {
		String a0 = "abc";
		String b0 = "abc";
		if (a0 == b0) {
			System.out.print("==");
		} else {
			System.out.print("!=");
		}
	}
}

The output result is: ==

So we can say the behavior of String when we define in the way that it just looks like a basic data type. Way? Because it can share in the stack. For instance, if we define twice of this statement: int x = 1, in program you write like this: int b = 1; int c = 1;. The JVM will exactly allocate only one room to store this variable in the ram. The second time when JVM read the same statement will make the new variable refer to the room that has allocate in the first time.

But there’s a new problem. Have you thought what indeed will happen when String meet “+”. Let’s see a group of examples.

First:

public class Test {
	public static void main(String[] args) {
		String b0 = "abcdef";
		String a0 = "abc" + "def";
		if (a0 == b0) {
			System.out.print("==");
		} else {
			System.out.print("!=");
		}
	}
}

The output result is: ==

Second:

public class Test {
	public static void main(String[] args) {
		String a0 = "abc";
		String b0 = "def";
		String c0 = a0 + b0;
		String d0 = "abcdef";
		if (c0 == d0) {
			System.out.print("==");
		} else {
			System.out.print("!=");
		}
	}
}

The answer is: !=

And the Third:

public class Test {
	public static void main(String[] args) {
		String a0 = new String("abc") + new String("def");
		String b0 = "abcdef";
		if (a0 == b0) {
			System.out.print("==");
		} else {
			System.out.print("!=");
		}
	}
}

The answer is: !=

According to the above examples, we find example 2 and example 3 should do the same thing in JVM. In other words, JVM have done the several steps when it go through the statement of “String a0 = “abc”; String b0 = “bcd”; String c0 = a0 + b0;” :

  1. String a0 = new String(“abc”);
  2. String b0 = new String(“def”);
  3. String c0 = a0 + b0;

These three steps can be abbreviated to String c0 = new String(“abc”) + new String(“def”).

Now, with that in mind. Have you find something stranger about

		String b0 = "abcdef";
		String a0 = "abc" + "def";

What indeed the JVM did when it went through the two statement?

Undoubtedly, the first statement is the same with “String bo = new String(“abcdef”);” because it’s the first time meeting this string. Well, now comes the complex. In row 2, JVM have done these:
“abc” + “def” become “abcdef” when compile into .class file
attention: JVM will not create an object of String(“abc”) or String(“def”) because the statement of “abc” + “def” has been compiled into “abcdef”!!

With these analysis above, we should at least remember two things:

  1. String is not a normal Object type. It has been optimized mostly.
  2. JVM do not always do the most effective things, sometimes it will do something useless, but it have to.

At last, here is a more interesting example:

public class Test {
	public static void main(String[] args) {
		String a = new String("abc");
		String b = "abc";
		String c = a.intern();
		System.out.println(c == b);
	}
}

The answer is true!