Pankaj Sejwal
Pankaj Sejwal

Reputation: 1595

string instantiation vs stringbuffer instantiation

I am not able to figure out that if

String ab = "hello";        //straight initialization

String ab_1 = new String ("hello_1");  //initializing using new

both work, but

StringBuffer bfr = new StringBuffer("hi");   //works only with new

works only if created with new.

Why it is that String can be instantiated directly but StringBuffer needs new operator. Can someone explain me the main reason please.

Upvotes: 4

Views: 3434

Answers (8)

camleng
camleng

Reputation: 1028

Basically, since Strings are used so much, Java offers a shorthand solution to instantiating a String.

Instead of always using this,

String str = new String ("hello");

Java makes it able to do this:

String str = "hello";

Upvotes: 0

Andreas
Andreas

Reputation: 5335

There is also one more difference based on 'where' strings are 'stored' - memory or string constant pool.

To make Java more memory efficient, the JVM sets aside a special area of memory called the "String constant pool." When the compiler encounters a String literal, it checks the pool to see if an identical String already exists. If a match is found, the reference to the new literal is directed to the existing String, and no new String literal object is created. (The existing String simply has an additional reference.)

String s = "abc"; // creates one String object and one reference variable

In this simple case, "abc" will go in the pool and s will refer to it.

String s = new String("abc"); // creates two objects, and one reference variable

In this case, because we used the new keyword, Java will create a new String object in normal (nonpool) memory, and s will refer to it. In addition, the literal "abc" will be placed in the pool.

Upvotes: 1

Thorn
Thorn

Reputation: 4057

Using String s1 = "hello"; and String s2 = new String("hello"); have a subtle difference.

 public static void main(String[] arg ) {
    String s1 = "Java";
    String s2 = "Java";
    String s3 = new String("Java");
    System.out.println(s1==s2); //true
    System.out.println(s1==s3); //false

    StringBuilder sb = new StringBuilder(25); //initial capacikacity
    sb = new StringBuilder(10);
    sb.append(s1).append(" uses immutable strings.");
    sb.setCharAt(20, 'S');
    System.out.println(sb);
}

In the above code, "Java" is known as a String literal. In order to save memory, both times this appears in the code, it is the same String literal, so s1 and s2 actually refer to the same object in memory. While s1.equals(s3) would be true, they do not reference the same object in memory as shown above.

In practice, we always use .equals to compare Strings and they are immutable, so we cannot change the data s1 refers to (at least not easily). But if we were able to change the data referenced by s1, then s2 would change along with it.

StringBuilder does let you modify the underlying data: we often use it to append one String to another as illustrated above. We can be glad that StringBuilder sb2 = "what?" is illegal because in the case of StringBuilders, having two of them reference the same data (meaning sb1==sb2) is more likely to lead to problems where a change in sb1 causes an unexpected change in sb2.

Upvotes: 2

neo
neo

Reputation: 1074

String is a mutable class and has in-build constructors which can create String object from the string literal.

There is no exception in case of String also (like creating it like primitive .e.g int i =0). String also executes constructor to initialize following (just difference is its abstract and not directly visible) :

String str = "ABC";

Becuase here "ABC" also represent one String object which can not be used directly by programmer but it resides in the String pool. And when this statement will be executed JVM will internally call the private constructor to create object using the "ABC" object which resides in the pool.

Upvotes: 0

Petr
Petr

Reputation: 63399

Strings are handle specially by java compiler. When you type a string literal such as "hello", the compiler creates a new String object for you internally.

No such thing is performed for StringBuffers (although Java uses StringBuffers internally for another purpose - for implementing string concatenation).

See Difference between string object and string literal for more details.

Other pointers:

Upvotes: 1

assylias
assylias

Reputation: 328785

All objects need to be instantiated with new. Only primitives can be instantiated from a literal (int i = 0;).

The only exceptions are:

  • strings, which allow a special initialisation construct:
   String s = "abc"; //can be instantiated from a literal, like primitives
  • null instantiation: Object o = null;

It is defined in the Java Language Specification #3.10:

A literal is the source code representation of a value of a primitive type, the String type, or the null type.

Note: arrays also have a dedicated initialisation patterm , but that's not a literal:

   int[][] a = { { 00, 01 }, { 10, 11 } };

Upvotes: 6

pcalcao
pcalcao

Reputation: 15990

Strings are quite a special case in Java (this is not really a good thing in my opinion, but that doesn't matter).

Strings, unlike other objects, can be instantiated directly like they were constants. When you do this, the String constant is added to the String constant pool, and handled like it was a primitive. Let me give an example.

String a = "abc";
String b = "abc";

When you instantiate a as a "primitive" string, it gets added to the pool, when you instantiate b, the same object is returned from the pool, so if you do this:

a == b;

You'll get... true, since it's actually the same object. If you instantiate both with new, you'll get false, since you're comparing the references of two different Objects (new forces the creation of a distinct object).

Upvotes: 1

amicngh
amicngh

Reputation: 7899

 String ab = "hello";        //straight initialization
 String ac = "hello";  // create one more reference ac

String is a special case when you use the new keyword, a new String object will be created. Note that objects are always on the heap - the string pool is not a separate memory area that is separate from the heap.The string pool is like a cache.

It is like this because Strings are something heavily used by java and creating String objects using new key word is expensive also that's why java has introduced StringPool concept.

If you declare one variable ac with same value , java will not create new object(String) it will simply refer to the same object(hello) which is already there in pool.

 String ab_1 = new String ("hello_1");  //initializing using new

It will simple create object in memory and ab_1 will refer to that object.

Upvotes: 1

Related Questions