-2
String s ="hello";
String s= new String ("hello");
String s1= new String("hello");

how is the string object created internally in above the cases.

String s = null;
String s = new String (null);  // I get a compilation error at this line

im not getting the object instantiation in above cases. Java doc says it creates a new obj / creates a new obj with original parameter as string.

but im still not clear

chollida
  • 7,834
  • 11
  • 55
  • 85
voldy
  • 359
  • 1
  • 8
  • 21
  • 1
    What exactly don't you understand in the javadoc, and in the error message you get from the compiler? – JB Nizet May 24 '13 at 20:09
  • 3
    Do not create `String` instances using the `new` operator. It's a waste of memory. – toniedzwiedz May 24 '13 at 20:09
  • The constructor String(String) is ambiguous-- the compiler error i get – voldy May 24 '13 at 20:11
  • This seems like a real question to me. The community really should do a better job. If there's other problems with it, then take the time and enumerate them. – jww Jul 11 '15 at 01:25

6 Answers6

3

Java uses the Flyweight design pattern to manage String instances in JVM. This pattern in short comes down to sharing objects that could potentially have too many instances to store.

String s ="hello";

Here, the JVM first checked in the String pool if "hello" already existed. If it did, s starts pointing to it directly. Otherwise, first "hello" gets added to the pool and then s points to it.

String s= new String ("hello");

Here, the literal string "hello" was already present in the String pool but the use of new still goes ahead and creates a new String object on the heap with the same value "hello".

String s1= new String("hello");

Same as above. We have three String objects by now.

String s = null;

Here, you've simple initialized a variable to null. Nothing special going on here.

String s = new String (null);

This won't work because String constructor is overloaded. It may take a String; it may take a char[] as well. But when you pass it a null compiler doesn't know which constructor to invoke because it doesn't have any data type to make a match on and hence it gives you an ambiguity error.

Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89
  • The first part is incorrect. All string literals are already in the constant pool, by definition. They are put there by the compiler. No check by the JVM necessary. – user207421 May 25 '13 at 00:36
  • @EJP This is implementation specific. What you're saying is nowhere guaranteed in the spec. – Ravi K Thapliyal May 25 '13 at 00:47
  • No it isn't. It is defined by the bytecode. The compiler emits bytecode that refers to an existing constant pool entry, or that calls `StringBuilder.append()/toString()` to create a new string. It has nothing to do with the JVM at all. – user207421 May 28 '13 at 01:51
  • @EJP As far as I know "string pool" is initially empty ([my reference](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern())) which causes me to believe that strings (and I mean literals here) are interned as and when encountered and use an already existing entry whenever possible. I'll appreciate if you could share something official that documents that things work the way you said. – Ravi K Thapliyal May 28 '13 at 06:51
2

String objects are created in the string pool, which is implemented in jvm to create and store string objects internally. Best way to create a String is String s ="hello";

String s= new String ("hello");

creates 2 String objects which is not necessary.

Pravat Panda
  • 1,060
  • 2
  • 13
  • 27
1

A String literal like "hello" is a rare piece of syntactic sugar in Java. It's not the same as calling the constructor, but it will give you a reference to an equal String object from the string pool in PermGen. Your compiler error is because the String class has overloaded constructors, and the compiler can't tell which one you're calling when you pass null.

Tap
  • 6,332
  • 3
  • 22
  • 25
  • yeah thanx i got it now – voldy May 24 '13 at 20:13
  • 3
    A string literal doesn't call the `String` constructor, it loads the specified string from permgen. String interning and all that. – yshavit May 24 '13 at 20:13
  • Thanks @yshavit, I have read that. I suppose I should qualify my statement that a string literal creates a string object like a constructor would. – Tap May 24 '13 at 20:18
  • @Tap Only once per JVM, though. `String s1 = "hello"; String s2 = "hello";` creates only _one_ String object. On the other hand, `String s1 = new String("hello"); String s2 = new String("hello");` creates three -- one for the literal, and then the two that invoked the `new String` constructor. – yshavit May 24 '13 at 20:22
  • 1
    True again. It would be more accurate for me to have said that both are means of getting a reference to a String object composed of those characters. – Tap May 24 '13 at 20:38
  • 2
    You should edit your answer or something... because using the literal `"hello"` is not at all identical to calling `new String("hello")` (see the comment made by @yshavit). – Alex Lockwood May 24 '13 at 23:12
  • I updated it. What I meant to communicate was that the semantic difference is rarely important to an application developer. – Tap May 25 '13 at 02:09
1

The Java compiler does some optimizations over strings to prevent having multiple String objects with the same value. It is called "string interning". That's why String in Java is not mutable. In the first case, what you are actually doing is assigning the reference of an existing String object to a new variable. You can think of that as if you have any other class instantiated and you assign it to another variable:

WhateverClass object1 = new WhateverClass();
WhateverClass object2 = object1; // No new instance created, just assigning a reference
boolean areEquals = object1 == object2; // This is true, same reference
String string1 = "foo";
String string2 = "foo";
String string3 = new String("foo");
areEquals = string1 == string2; // true, same reference
areEquals = string1 == string3; // false, different objects

However, using "new" you are forcing to create a new instance (more memory taken, slower...), so you should avoid that as much as possible. The compilation error with the null parameter in the String constructor is a completely different story.

Community
  • 1
  • 1
MaQy
  • 478
  • 3
  • 10
0

String and other classes that extends of Number (like Integer) uses a pool to store some objects so when you ask for them are already created. In String class all literal strings and string-valued constant expressions are interned , this is call String interning. So when you create a String with " " all these strings are interned (created if they don't or retrieved if they exist) . Is similar to the flyweight pattern.

 String s = new String(null) // doesnt compile cause it's ambiguous
 String s = new String((String)null) // u can try this, but u will have a RuntimeException(NullPointerException) if u use this variable for something

So if you want to test

String s = new String("hello");  // "hello" is interned cause it's a literal and with the new clause u waste memory, cause u create max 2 times, one in the heap  and the other in permgen"
String s2 = "hello";
String s3 = "hello";
   System.out.println(s==s2); // false
   System.out.println(s2 == s3); // true
   System.out.println(s.equals(s2));//true
nachokk
  • 14,363
  • 4
  • 24
  • 53
  • All String objects are not cached. -1 – user207421 May 25 '13 at 00:34
  • @EJP Sorry, all literal strings and string-valued constant expressions are interned. – nachokk Jun 11 '13 at 18:29
  • So edit your answer accordingly. And it isn't called 'object internation'. You just made that up. There is a major difference between interning and caching which you don't appear to have grasped. – user207421 Jun 15 '13 at 10:33
  • @EJP i edited. Yes is confusing cause Integer class call `IntegerCache` where store values that are intern – nachokk Jun 15 '13 at 14:36
-1

In Java the Objects are instantiated with their references. If you create a String "Hello", in the stack will be created a reference(pointer) to a String. So if you write: String s = null the reference will be instantiated but without any pointer to a String. If you write new String(null) it will have to create a pointer to a null memory area, here's why you get that compilation error. Hope to help, Simo

Spale350z
  • 15
  • 4