Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't we use new operator while initializing a string?

Tags:

c#

.net

I was asked this question in an interview: Is string a reference type or a value type.

I said its a reference type. Then he asked me why don't we use new operator while initializing the string ? I said because the c# language has a simpler syntax for creating a string and the compiler automatically converts the code into a call for the construcor of the System.String class.

Is this answer correct or not ?

like image 807
teenup Avatar asked Jul 25 '10 09:07

teenup


People also ask

Why new keyword is not used in String?

String message = new String("Hai"); new String("Hai") is a new String object. In this case, even if the literal "Hai" was already in the string literal pool, a new object is created. This is not recommended because chances are that you might end with more than one String objects with the same value.

Can we use a new operator on String to create a String object?

It is a Pool of Strings stored in the Heap Memory. All the strings created are stored in this pool if they do not already exist in the pool. String class is immutable class and hence all string objects created using literals or new operators cannot be changed/modified.

What happens when we create String using new operator?

So, in your case : String a = new String("abc"); "abc" will be resolved as a compile time constant and thus will be added to the String constants pool for the current JVM. Next, the value of a will be resolved at run-time and will be added to the heap during run-time.

Can you initialize a String?

Initialize a string by passing a literal, quoted character array as an argument to the constructor. Initialize a string using the equal sign (=). Use one string to initialize another. These are the simplest forms of string initialization, but variations offer more flexibility and control.


2 Answers

Strings are immutable reference types. There's the ldstr IL instruction which allows pushing a new object reference to a string literal. So when you write:

string a = "abc"; 

The compiler tests if the "abc" literal has already been defined in the metadata and if not declare it. Then it translates this code into the following IL instruction:

ldstr "abc" 

Which basically makes the a local variable point to the string literal defined in the metadata.

So I would say that your answer is not quite right as the compiler doesn't translate this into a call to a constructor.

like image 77
Darin Dimitrov Avatar answered Oct 02 '22 21:10

Darin Dimitrov


Not exactly the right answer. Strings are "special" reference types. They are immutable. You are right that compiler does something internally, but it is not the constructor call. It calls ldstr which pushes a new object reference to a string literal stored in the metadata.

Sample C# code :

class Program {     static void Main()     {         string str;         string initStr = "test";     } } 

and here is the IL code

.method private hidebysig static void  Main() cil managed {   .entrypoint   // Code size       8 (0x8)   .maxstack  1   .locals init ([0] string str,            [1] string initStr)   IL_0000:  nop   IL_0001:  ldstr      "test"   IL_0006:  stloc.1   IL_0007:  ret } // end of method Program::Main 

You can see ldstr call above.

Even more due to immutability of the Strings it becomes possible to keep only distinct/unique strings. All strings are kept in the hash table where the key is the string value and the value is the reference to that string. Each time when we have a new string CLR checks is there already such a string in the hash table. If there is then no new memory is allocated and the reference is set to this existing string.

You can run this code to check :

class Program {     static void Main()     {         string someString = "abc";         string otherString = "efg";          // will retun false         Console.WriteLine(Object.ReferenceEquals(someString, otherString));          someString = "efg";          // will return true         Console.WriteLine(Object.ReferenceEquals(someString, otherString));     } }     
like image 20
Incognito Avatar answered Oct 02 '22 21:10

Incognito