Related
I'm new to programming and as I was using some strings in Java I could not figure out this probably simple question:
If we have method:
public static String str(String arg)
{
return arg;
}
Is there any difference between those two samples below?
System.out.println("Hello");
vs
System.out.println(Someclass.str("Hello"));
What is processed faster? Is it better to set arguments of methods using return value of different method or using chosen datatype directly? Is there any practical use of second sample?
Thanks and sorry if it's dumb question.
There is no difference, except that the second example is more obfuscatory, the method call doesn't add any value. Run this code:
"Hello".equals(Someclass.str("Hello"));
It will return true, that tells you that the strings are equivalent.
All the method in the second example does is take the reference passed in and return it, so the code
String s = "Hello";
System.out.println(Someclass.str(s) == s);
will print true; s and Someclass.str's return value should be the same reference.
Don't fixate on performance, try to write code that makes sense.
The first case is slightly faster and it makes no sense using the second one unless you are modifying the string in Someclass's str method.
In Java, all parameters are passed by value. This includes references to objects like Strings. When you call the str(String arg) method, you are not actually passing the String into the method, rather a copy of the reference that points to the String's location in memory. When you return arg, again, you are returning a copy of this reference to the String.
In your second example you are using a String literal. Java treats these in a special way (the compiler essentially creates a constant and substitutes that constant in place of the literal wherever you see it in code). So when you pass the literal in, you are actually passing a copy of the reference (memory location) of the literal, and then returning it. There is still only one String object.
In other words, all you are doing is adding a small amount of overhead by inserting the method call in the middle.
The first case is faster.
The second case is nonsensical. You are passing a String to a method which simply returns that same String object. There is absolutely no reason to do this. It will probably be a bit slower because of the unnecessary method call.
Using double quotes will already automatically create a String object.
And in any case, readable code far outweighs small performance boosts in all but the most demanding scenarios.
If I write this code :
String s = new String("TestString");
I understand how s refers to a string created dynamically. s is not an object in itself, but refers to one.
But I am not able to figure out what this means :
String s = "TestString";
Q1. If it would have been some primitive data type I would understand, but what does this signify for a class type ?
Q2. Is this kind of initialization allowed for user created classes as well ?
Java Level : Beginner
Q1. If it would have been some primitive data type I would understand, but what does this signify for a class type ?
In this case, "TestString" is a string literal. A string literal also serves as a reference to an instance of String. This is per the language specification, §3.10.5. So, in your particular case "TestString" is a reference to an instance of String, and you are assigning that same reference to your variable s.
Now, there are some rather special things about Strings that are referred to by literals. Two string literals with the same value (logically, as strings) always refer to the same instance of String. This is due to the "interning" of string literals.
However, when you say
String s = new String("TestString");
it is still the case that "TestString" refers to an instance of String, in fact to an instance in the string intern pool, but it is not the case that s refers to this same string. Instead, s is initialized to have its value equal to "TestString", but it is in fact a new reference. That is:
String s = new String("TestString");
String t = "TestString";
System.out.println(s == t);
This will print false.
Q2. Is this kind of initialization allowed for user created classes as well ?
No.
String s = "TestString";
Is the normal way to create a String. In fact when you do:
String s = new String("TestString");
What you're doing is create a string first, then passing it as an argument to new String(); So the question is not why the first one exists, but why the second one does. The answer is pretty subtle and you probably won't ever care: The first way creates a String literal that doesn't get garbage collected, and is shared on all the VM. The second one, instead, does. This means, for performance reasons, there are cases when you want to use the second form, like when working with very very large strings.
You can read more about it here:
http://kjetilod.blogspot.com.es/2008/09/string-constructor-considered-useless.html
From the Oracle Documentation:
The most direct way to create a string is to write:
String greeting = "Hello world!";
In this case, "Hello world!" is a string literal—a series of
characters in your code that is enclosed in double quotes. Whenever it
encounters a string literal in your code, the compiler creates a
String object with its value—in this case, Hello world!.
As with any other object, you can create String objects by using the
new keyword and a constructor.
Q1. If it would have been some primitive data type I would understand,
but what does this signify for a class type ?
No, this is special case, in case of String literals, String s = "someString" statement means we are referring to someString which is stored in string constant pool. someString will be an instance of String class but will be stored in string literal pool.
The special thing about String literal pool will be.
String s = "someString";
String s1 = "someString";
Here, s == s1' will returntrue` as they will refer to the same object in string literal pool.
String s2 = new String("someString");
String s3 = new String("someString");
Here, s2 == s3 will return false as both string will be created in non-constant pool memory.
You can find a good tutorial regarding strings here
http://www.thejavageek.com/2013/06/19/the-string-constant-pool/
http://www.thejavageek.com/2013/06/17/string-immutability-in-java/
Q2. Is this kind of initialization allowed for user created classes as
well ?
No we can't.
I need to know the difference of initializing the String in java when using the runtime.
For Exmaple:
String declare = null;
otherwise:
String declare = "";
I declared the two type of declaration of string. Which one is best for runtime declaration.
A String is an object. If you initialize it to null, you are telling the compiler that you are aware that wasn't initialized, and that there should be no warnings when you first try to use the variable. Aside from that, you are pointing a reference to null, of course.
If you initialize the String to an empty String, however, the following happens:
There's now a String object allocated
The compiler will put that String literal in the String pool
Any other String that you initialize to "" will point to the same inmutable String from that pool
So, the question is, how do you handle nulls or empty Strings in your code? That's what should guide your decision
In first case you have created a 'pointer' to a null object (objec is not created). In second one - the 'pointer' to the object with value "" (empty string). These are qiute different things - you need to decide, which one do you need for further manipulations.
First example will not create a String object, and second will. So, the statement:
declare.equals("some string");
will generate a NullPointerException for your first example, but not for the second.
As #AljoshaBre commented, it depends on what you are going to do with it. Having it initialized to null is somewhat redundant, for the initial value usually is that. The blank initialization ("") makes it impossible to receive a null pointer exception if you go through an unexpected path (which may be good or bad, because it might mask logic errors in your code).
Having an initial value is usually good, but make it so that it is meaningful for the code that is going to use your String, not a random initial value.
Often I have a class as such:
public class Foo
{
private String field1;
private String field2;
// etc etc etc
}
This makes the initial values of field1 and field2 equal to null. Would it be better to have all my String class fields as follows?
public class Foo
{
private String field1 = "";
private String field2 = "";
// etc etc etc
}
Then, if I'm consistent with class definition I'd avoid a lot of null pointer problems. What are the problems with this approach?
That way lies madness (usually). If you're running into a lot of null pointer problems, that's because you're trying to use them before actually populating them. Those null pointer problems are loud obnoxious warning sirens telling you where that use is, allowing you to then go in and fix the problem. If you just initially set them to empty, then you'll be risking using them instead of what you were actually expecting there.
Absolutely not. An empty string and a null string are entirely different things and you should not confuse them.
To explain further:
"null" means "I haven't initialized
this variable, or it has no value"
"empty string" means "I know what the value is, it's empty".
As Yuliy already mentioned, if you're seeing a lot of null pointer exceptions, it's because you are expecting things to have values when they don't, or you're being sloppy about initializing things before you use them. In either case, you should take the time to program properly - make sure things that should have values have those values, and make sure that if you're accessing the values of things that might not have value, that you take that into account.
Does it actually make sense in a specific case for the value to be used before it is set somewhere else, and to behave as an empty String in that case? i.e. is an empty string actually a correct default value, and does it make sense to have a default value at all?
If the answer is yes, setting it to "" in the declaration is the right thing to do. If not, it's a recipe for making bugs harder to find and diagnose.
I disagree with the other posters. Using the empty string is acceptable. I prefer to use it whenever possible.
In the great majority of cases, a null String and an empty String represent the exact same thing - unknown data. Whether you represent that with a null or an empty String is a matter of choice.
Generally it would be best to avoid this. A couple of reasons:
Getting a NullPointerException is generally a good warning that you are using a variable before you should be, or that you forgot to set it. Setting it to an empty string would get rid of the NullPointerException, but would likely cause a different (and harder to track down) bug further down the line in your program.
There can be a valid difference between null and "". A null value usually indicates that no value was set or the value is unknown. An empty string indicates that it was deliberately set to be empty. Depending on your program, that subtle difference could be important.
I know this is an old question but I wanted to point out the following:
String s = null;
s += "hello";
System.out.println(s);// this will return nullhello
whereas
String s = "";
s += "hello";
System.out.println(s); // this will return hello
obviously the really answer to this is that one should use StringBuffer rather than just concatenate strings but as we all know that for some code it is just simpler to concatenate.
I would suggest neither.
Instead you should give your fields sensible values. If they don't have to change, I would make them final.
public class Foo {
private final String field1;
private final String field2;
public Foo(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
// etc.
}
No need to assign, i'm-not-initialised-yet values. Just give it the initial values.
I would avoid doing this, you need to know if your instances aren't getting populated with data correctly.
Null is better, that is why they are called unchecked exceptions {Null pointer exception}. When the exception is thrown, it tells you that you have to initialize it to some non null value before calling any methods on it.
If you do
private String field1 = "";
You are trying to supress the error. It is hard to find the bug, later.
I think when you use String s = null it will create variable "s" on stack only and no object will exists on heap,but as soon as you declare things as like String s=""; what it will does is like it will create "" object on heap.As we know that Strings are immutable so whenever u wil assign new value to string varible everytime it will create new Object on heap...So I think String s=null is efficient than String s = "";
Suggestions are welcome!!!!!
No way. Why do you want to do that? That will give incorrect results. nulls and """ are not same.
What exactly does immutable mean - that is, what are the consequences of an object being mutable or immutable? In particular, why are Java's Strings immutable?
My understanding is that the StringBuilder type is something like a mutable equivalent to String. When would I use StringBuilder rather than String, and vice-versa?
Immutable means that once the constructor for an object has completed execution that instance can't be altered.
This is useful as it means you can pass references to the object around, without worrying that someone else is going to change its contents. Especially when dealing with concurrency, there are no locking issues with objects that never change
e.g.
class Foo
{
private final String myvar;
public Foo(final String initialValue)
{
this.myvar = initialValue;
}
public String getValue()
{
return this.myvar;
}
}
Foo doesn't have to worry that the caller to getValue() might change the text in the string.
If you imagine a similar class to Foo, but with a StringBuilder rather than a String as a member, you can see that a caller to getValue() would be able to alter the StringBuilder attribute of a Foo instance.
Also beware of the different kinds of immutability you might find: Eric Lippert wrote a blog article about this. Basically you can have objects whose interface is immutable but behind the scenes actual mutables private state (and therefore can't be shared safely between threads).
An immutable object is an object where the internal fields (or at least, all the internal fields that affect its external behavior) cannot be changed.
There are a lot of advantages to immutable strings:
Performance: Take the following operation:
String substring = fullstring.substring(x,y);
The underlying C for the substring() method is probably something like this:
// Assume string is stored like this:
struct String { char* characters; unsigned int length; };
// Passing pointers because Java is pass-by-reference
struct String* substring(struct String* in, unsigned int begin, unsigned int end)
{
struct String* out = malloc(sizeof(struct String));
out->characters = in->characters + begin;
out->length = end - begin;
return out;
}
Note that none of the characters have to be copied! If the String object were mutable (the characters could change later) then you would have to copy all the characters, otherwise changes to characters in the substring would be reflected in the other string later.
Concurrency: If the internal structure of an immutable object is valid, it will always be valid. There's no chance that different threads can create an invalid state within that object. Hence, immutable objects are Thread Safe.
Garbage collection: It's much easier for the garbage collector to make logical decisions about immutable objects.
However, there are also downsides to immutability:
Performance: Wait, I thought you said performance was an upside of immutability! Well, it is sometimes, but not always. Take the following code:
foo = foo.substring(0,4) + "a" + foo.substring(5); // foo is a String
bar.replace(4,5,"a"); // bar is a StringBuilder
The two lines both replace the fourth character with the letter "a". Not only is the second piece of code more readable, it's faster. Look at how you would have to do the underlying code for foo. The substrings are easy, but now because there's already a character at space five and something else might be referencing foo, you can't just change it; you have to copy the whole string (of course some of this functionality is abstracted into functions in the real underlying C, but the point here is to show the code that gets executed all in one place).
struct String* concatenate(struct String* first, struct String* second)
{
struct String* new = malloc(sizeof(struct String));
new->length = first->length + second->length;
new->characters = malloc(new->length);
int i;
for(i = 0; i < first->length; i++)
new->characters[i] = first->characters[i];
for(; i - first->length < second->length; i++)
new->characters[i] = second->characters[i - first->length];
return new;
}
// The code that executes
struct String* astring;
char a = 'a';
astring->characters = &a;
astring->length = 1;
foo = concatenate(concatenate(slice(foo,0,4),astring),slice(foo,5,foo->length));
Note that concatenate gets called twice meaning that the entire string has to be looped through! Compare this to the C code for the bar operation:
bar->characters[4] = 'a';
The mutable string operation is obviously much faster.
In Conclusion: In most cases, you want an immutable string. But if you need to do a lot of appending and inserting into a string, you need the mutability for speed. If you want the concurrency safety and garbage collection benefits with it the key is to keep your mutable objects local to a method:
// This will have awful performance if you don't use mutable strings
String join(String[] strings, String separator)
{
StringBuilder mutable;
boolean first = true;
for(int i = 0; i < strings.length; i++)
{
if(first) first = false;
else mutable.append(separator);
mutable.append(strings[i]);
}
return mutable.toString();
}
Since the mutable object is a local reference, you don't have to worry about concurrency safety (only one thread ever touches it). And since it isn't referenced anywhere else, it is only allocated on the stack, so it is deallocated as soon as the function call is finished (you don't have to worry about garbage collection). And you get all the performance benefits of both mutability and immutability.
Actually String is not immutable if you use the wikipedia definition suggested above.
String's state does change post construction. Take a look at the hashcode() method. String caches the hashcode value in a local field but does not calculate it until the first call of hashcode(). This lazy evaluation of hashcode places String in an interesting position as an immutable object whose state changes, but it cannot be observed to have changed without using reflection.
So maybe the definition of immutable should be an object that cannot be observed to have changed.
If the state changes in an immutable object after it has been created but no-one can see it (without reflection) is the object still immutable?
Immutable objects are objects that can't be changed programmatically. They're especially good for multi-threaded environments or other environments where more than one process is able to alter (mutate) the values in an object.
Just to clarify, however, StringBuilder is actually a mutable object, not an immutable one. A regular java String is immutable (meaning that once it's been created you cannot change the underlying string without changing the object).
For example, let's say that I have a class called ColoredString that has a String value and a String color:
public class ColoredString {
private String color;
private String string;
public ColoredString(String color, String string) {
this.color = color;
this.string = string;
}
public String getColor() { return this.color; }
public String getString() { return this.string; }
public void setColor(String newColor) {
this.color = newColor;
}
}
In this example, the ColoredString is said to be mutable because you can change (mutate) one of its key properties without creating a new ColoredString class. The reason why this may be bad is, for example, let's say you have a GUI application which has multiple threads and you are using ColoredStrings to print data to the window. If you have an instance of ColoredString which was created as
new ColoredString("Blue", "This is a blue string!");
Then you would expect the string to always be "Blue". If another thread, however, got ahold of this instance and called
blueString.setColor("Red");
You would suddenly, and probably unexpectedly, now have a "Red" string when you wanted a "Blue" one. Because of this, immutable objects are almost always preferred when passing instances of objects around. When you have a case where mutable objects are really necessary, then you would typically guard the objet by only passing copies out from your specific field of control.
To recap, in Java, java.lang.String is an immutable object (it cannot be changed once it's created) and java.lang.StringBuilder is a mutable object because it can be changed without creating a new instance.
In large applications its common for string literals to occupy large bits of memory. So to efficiently handle the memory, the JVM allocates an area called "String constant pool".(Note that in memory even an unreferenced String carries around a char[], an int for its length, and another for its hashCode. For a number, by contrast, a maximum of eight immediate bytes is required)
When complier comes across a String literal it checks the pool to see if there is an identical literal already present. And if one 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 gets an additional reference).
Hence : String mutability saves memory...
But when any of the variables change value, Actually - it's only their reference that's changed, not the value in memory(hence it will not affect the other variables referencing it) as seen below....
String s1 = "Old string";
//s1 variable, refers to string in memory
reference | MEMORY |
variables | |
[s1] --------------->| "Old String" |
String s2 = s1;
//s2 refers to same string as s1
| |
[s1] --------------->| "Old String" |
[s2] ------------------------^
s1 = "New String";
//s1 deletes reference to old string and points to the newly created one
[s1] -----|--------->| "New String" |
| | |
|~~~~~~~~~X| "Old String" |
[s2] ------------------------^
The original string 'in memory' didn't change, but the
reference variable was changed so that it refers to the new string.
And if we didn't have s2, "Old String" would still be in the memory but
we'll not be able to access it...
"immutable" means you cannot change value. If you have an instance of String class, any method you call which seems to modify the value, will actually create another String.
String foo = "Hello";
foo.substring(3);
<-- foo here still has the same value "Hello"
To preserve changes you should do something like this
foo = foo.sustring(3);
Immutable vs mutable can be funny when you work with collections. Think about what will happen if you use mutable object as a key for map and then change the value (tip: think about equals and hashCode).
java.time
It might be a bit late but in order to understand what an immutable object is, consider the following example from the new Java 8 Date and Time API (java.time). As you probably know all date objects from Java 8 are immutable so in the following example
LocalDate date = LocalDate.of(2014, 3, 18);
date.plusYears(2);
System.out.println(date);
Output:
2014-03-18
This prints the same year as the initial date because the plusYears(2) returns a new object so the old date is still unchanged because it's an immutable object. Once created you cannot further modify it and the date variable still points to it.
So, that code example should capture and use the new object instantiated and returned by that call to plusYears.
LocalDate date = LocalDate.of(2014, 3, 18);
LocalDate dateAfterTwoYears = date.plusYears(2);
date.toString()… 2014-03-18
dateAfterTwoYears.toString()… 2016-03-18
I really like the explaination from SCJP Sun Certified Programmer for Java 5 Study Guide.
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.
Objects which are immutable can not have their state changed after they have been created.
There are three main reasons to use immutable objects whenever you can, all of which will help to reduce the number of bugs you introduce in your code:
It is much easier to reason about how your program works when you know that an object's state cannot be changed by another method
Immutable objects are automatically thread safe (assuming they are published safely) so will never be the cause of those hard-to-pin-down multithreading bugs
Immutable objects will always have the same Hash code, so they can be used as the keys in a HashMap (or similar). If the hash code of an element in a hash table was to change, the table entry would then effectively be lost, since attempts to find it in the table would end up looking in the wrong place. This is the main reason that String objects are immutable - they are frequently used as HashMap keys.
There are also some other optimisations you might be able to make in code when you know that the state of an object is immutable - caching the calculated hash, for example - but these are optimisations and therefore not nearly so interesting.
One meaning has to do with how the value is stored in the computer, For a .Net string for example, it means that the string in memory cannot be changed, When you think you're changing it, you are in fact creating a new string in memory and pointing the existing variable (which is just a pointer to the actual collection of characters somewhere else) to the new string.
String s1="Hi";
String s2=s1;
s1="Bye";
System.out.println(s2); //Hi (if String was mutable output would be: Bye)
System.out.println(s1); //Bye
s1="Hi" : an object s1 was created with "Hi" value in it.
s2=s1 : an object s2 is created with reference to s1 object.
s1="Bye" : the previous s1 object's value doesn't change because s1 has String type and String type is an immutable type, instead compiler create a new String object with "Bye" value and s1 referenced to it. here when we print s2 value, the result will be "Hi" not "Bye" because s2 referenced to previous s1 object which had "Hi" value.
Immutable means that once the object is created, non of its members will change. String is immutable since you can not change its content.
For example:
String s1 = " abc ";
String s2 = s1.trim();
In the code above, the string s1 did not change, another object (s2) was created using s1.
Immutable simply mean unchangeable or unmodifiable. Once string object is created its data or state can't be changed
Consider bellow example,
class Testimmutablestring{
public static void main(String args[]){
String s="Future";
s.concat(" World");//concat() method appends the string at the end
System.out.println(s);//will print Future because strings are immutable objects
}
}
Let's get idea considering bellow diagram,
In this diagram, you can see new object created as "Future World". But not change "Future".Because String is immutable. s, still refer to "Future". If you need to call "Future World",
String s="Future";
s=s.concat(" World");
System.out.println(s);//print Future World
Why are string objects immutable in java?
Because Java uses the concept of string literal. Suppose there are 5 reference variables, all refers to one object "Future".If one reference variable changes the value of the object, it will be affected to all the reference variables. That is why string objects are immutable in java.
Once instanciated, cannot be altered. Consider a class that an instance of might be used as the key for a hashtable or similar. Check out Java best practices.
As the accepted answer doesn't answer all the questions. I'm forced to give an answer after 11 years and 6 months.
Can somebody clarify what is meant by immutable?
Hope you meant immutable object (because we could think about immutable reference).
An object is immutable: iff once created, they always represent the same value (doesn't have any method that change the value).
Why is a String immutable?
Respect the above definition which could be checked by looking into the Sting.java source code.
What are the advantages/disadvantages of the immutable objects?
immutable types are :
safer from bugs.
easier to understand.
and more ready for change.
Why should a mutable object such as StringBuilder be preferred over String and vice-verse?
Narrowing the question Why do we need the mutable StringBuilder in programming?
A common use for it is to concatenate a large number of strings together, like this:
String s = "";
for (int i = 0; i < n; ++i) {
s = s + n;
}
Using immutable strings, this makes a lot of temporary copies — the first number of the string ("0") is actually copied n times in the course of building up the final string, the second number is copied n-1 times, and so on. It actually costs O(n2) time just to do all that copying, even though we only concatenated n elements.
StringBuilder is designed to minimize this copying. It uses a simple but clever internal data structure to avoid doing any copying at all until the very end, when you ask for the final String with a toString() call:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; ++i) {
sb.append(String.valueOf(n));
}
String s = sb.toString();
Getting good performance is one reason why we use mutable objects. Another is convenient sharing: two parts of your program can communicate more conveniently by sharing a common mutable data structure.
More could be found here : https://web.mit.edu/6.005/www/fa15/classes/09-immutability/#useful_immutable_types
Immutable Objects
An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.
Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.
Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a new object as opposed to updating an object in place. The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated with immutable objects. These include decreased overhead due to garbage collection, and the elimination of code needed to protect mutable objects from corruption.
The following subsections take a class whose instances are mutable and derives a class with immutable instances from it. In so doing, they give general rules for this kind of conversion and demonstrate some of the advantages of immutable objects.
Source
An immutable object is the one you cannot modify after you create it. A typical example are string literals.
A D programming language, which becomes increasingly popular, has a notion of "immutability" through "invariant" keyword. Check this Dr.Dobb's article about it - http://dobbscodetalk.com/index.php?option=com_myblog&show=Invariant-Strings.html&Itemid=29 . It explains the problem perfectly.