String confusion in java [duplicate] - java

This question already has answers here:
Immutability of Strings in Java
(26 answers)
Closed 9 years ago.
From the oracle doc
String is immutable also Strings are constant; their values
cannot be changed after they are created. and because they are
immutable they can be shared. String buffers support mutable strings.
but I can always do the following:
String name="SO";
name="SE";
I can change the value so how can it be immutable and it is said that for security reason also like database connectivity etc..
Pardon me for asking such basic question but I need to understand.

name="SE" by doing this, you are changing the value of name variable, not the String object SO itself. String are immutable in the sense, String object SO can't be modified once created. By doing name = name+"TEST"; there will be a new String object SOTEST created in the memory, not existing String object SO will be modified.
For further details look here and here. There are lot of example and explanation.

Yes, you can change the string your name variable points to. But let's see what happens when you execute the following code sequence:
String name = "SO"; //line 1
name = "SE"; //line 2
At line 1: a new String object is created, that holds the value "SO";
At line 2: a new String object is created, that holds the value "SE"; your name variable value changes, in that it points to another reference, which is the second String object; the first String object ("SO") is still on the heap, but is not referenced anymore and is made available for future garbage collections, if any.
What you have to understand here is that, as soon as the String object containing the char sequence {'S', 'O'} is constructed, the char sequence wrapped by that String object could never change again. E.g. you cannot make that object wrap the char sequence {'S', 'E'}. That's what immutability is all about.

In the example you provide you have created two Strings. First a String SO is created and the reference is assigned to name. Then a new String is created, SE and that reference is assigned to name. You never actually modified the first String that was created.
String temp = "SO";
String name = temp;
name = "SE";
System.out.println(temp.equals("SO")); //prints true;
System.out.println(temp == name); //compares references prints false

When you change value of your String reference, you in fact create new object.And your reference now is linked to this new object.
String myValue = "old"; -> VM creates String object "old"
myValue = "new"; -> VM created String object "new"; "old" object still exists but any reference is linked to this, so we can say : "old" is lost

See for example the below image from the internet:
The big cloud is the heap where objects are being stored, s is the reference to the object (in your question you are using name as the reference)
When you do s = "abcd" a new object is created in the heap, and s is a reference to it. (Like the top arrow shows)
The important bit:
When you then do something like s = "abcdef" or s = s + "ef" the immutable string object "abcd" cannot be changed and so a new object is created and s loses it's reference to the old string (shown by dotted line) and now references the new String (Shown by the bottom arrow).
The old object I would assume is picked up by Garbage Collector at some point.

Related

In Java, Why String is non-primitive data type?

In Java, we can directly use String to declare a string variable name and specify its value. We do not have to define the string as an array by using new keyword, even though String is non-primitive data type.
Can someone please explain why String is non-primitive datatype?
String is non-primitive because only class can have methods. Primitive can not. And String need many functions to be called upon while processing like substring, indexof, equals, touppercase. It would not have been possible without making it class.
Also class has made it possible to make strings immutable and final to enhance security and efficiency by allowing pooling.
The String Javadoc clearly indicates that String is a subclass of Object; and further String.equals(Object) overrides Object.equals(Object).
JLS-3.10.5. String Literals specifies that
A string literal consists of zero or more characters enclosed in double quotes.
Also, JLS-4.3.3. The Class String adds
Instances of class String represent sequences of Unicode code points.
A String object has a constant (unchanging) value.
String literals (§3.10.5) are references to instances of class String.
The string concatenation operator + (§15.18.1) implicitly creates a new String object when the result is not a compile-time constant expression (§15.28).
It's also worth pointing out that arrays are also Object(s), and An Array of Characters is Not a String. Finally, if a String wasn't an Object it couldn't be null.
Yes String is an object in Java. The fact that it can be used similar to primitives does not contradict
Please refer - Strings are objects in Java, so why don't we use 'new' to create them?
String creats an Object each time you assign a value in its String Pool.
Where every time if you create a similar object it will look for that and refer, if that value is not there it will again create a new one. Study more on String Pool you will automatically come to know the difference.
String str = “This is string literal”;
This is string literal. When you declare string like this, you are actually calling intern() method on String. This method references internal pool of string objects. If there already exists a string value “This is string literal”, then str will reference of that string and no new String object will be created.
String str = new String(“this is string created by new operator”);
This is string object. In this method JVM is forced to create a new string reference, even if “this is string created by new operator” is in the reference pool.
String is object, is immutable, that means that you cannot change the object itself, but you can change the reference to the object.
This is how String works
String myStr = "test";
This as usual, creates a string named "test" and assign it a reference "myStr".
Important point to note here is, while the String object is immutable, its reference variable is not.
String is a Java Object and not a primitive data type.
String is part of the java.lang package that is imported by default in any java project.
There is no need to define an array of char, just use String.
Possible duplicate: Java String import
I think you are confusing 'primitive' and 'literal'. A primitive is a datatype that is not an object. A literal is a convenient way of describing the bit pattern for a datatype. For instance -1 describes the bit pattern 0xFFFFFFFF for an int,and 'a' describes the unicode code point for a lower case A in 16 bits (0x0061). Literals aren't restricted to describing primitive datatypes. You can describe an array. For instance, int[] a = {1, 2, 3};.
A string literal is just a way of describing an immutable array of characters with some methods attached. The literal is syntactic sugar for describing something that would otherwise be very complicated. For example:
String s = "ab";
Is much simpler than:
char[] c = new char[2];
c[0] = 'a';
c[1] = 'b';
String s = new String(c);
In Java, String is an object that stores the location to where the actual "value" of where the String is located.
You DO need to use the new keyword when making an array of Strings, as you do with making an array of anything else.
String[] text = new String[4]
This create's four String references that lead the computer to where the text is located at. Also, all Strings default to a value of null because until you give them a value to store at a memory address, there is nothing to be stored.
String is an array of characters
Primitive data types have limitations which fixed data type
but in strings size is vary so that is the main reason why the the strings are non primitive
String in Java is itself is a class and has its own methods to manipulate and operate over object of String class
Strings has its own feature that they are immutable.
Primitive data types are types that don't have a method. Whereas strings have method e.g. toupper, lowercase etc. In intellij you can check is there is a method or not.
this is showing the methods for the (int) which shows no methods(it is primitive
This image is showing the (String) which shows methods (it is not primitive)
Because string is actually a group of character (char) datatype. So it is being derived from char datatype. It have its origin datatype i. E. Char but int float chat etc do not have origin type. They are unique. Which is why string is derived datatype

If I have 2 reference types, with the same value, does that mean only 1 object in memory

I'm new to Java and have read a conflicting statement to what I believe. Please consider the following code.
String str1 = "dave";
String str2 = "dave";
Both str1 and str2, although unique variables, reference the exact same value. So, how many unique objects are created in memory? 1 or 2 and can some one explain why?
In your example they reference to the same object, because the strings are interned.
In general, usage of new creates new objects, thus using:
String str1 = new String("dave");
String str2 = new String("dave");
would create two different objects in the heap.
It's not so complicated. Except if you're talking about Strings ;-)
First, let's ignore Strings and assume this simple type:
public class ValueHolder {
private final int value;
public ValueHolder(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
If you have two lines like this:
ValueHolder vh1 = new ValueHolder(1);
ValueHolder vh2 = new ValueHolder(1);
then you'll have created exactly 2 objects on the heap. Even though they behave exactly the same and have the exact same values stored in them (and can't be modified), you will have two objects.
So vh1 == vh2 will return false!
The same is true for String objects: two String objects with the same value can exist.
However, there is one specific thing about String: if you use a String literal(*) in your code, Java will try to re-use any earlier occurance of this (via a process called interning).
So in your example code str1 and str2 will point to the same object.
(*) or more precisely: a compile-time constant expression of type String.
You have one unique Object & 2 references pointing to the same object. This is as a result of String pooling (or interning). Given that both String literals have identical content, the only way to ensure that 2 separate Objects could be created would be to to explicitly invoke one of the String constructors.
it depends. if you write a little test program, then there's a very good chance that they will contain the same reference, because java is trying to do you a favor by saving memory and reusing references. if str2 came from user input, then it would likely be two different references. a good way to test is to use == in a comparison. if the two are ==, then they are referencing the same memory location. if they are not, then they are two different references. this throws off a lot of beginning programmers because when they first start writing code, they use ==, see that it works, then down the road can't figure out why their comparisons aren't working.
i can't explain specifically when java does reuse references "behind the scenes" but it's related to how and when the values are created
You are writing a short-hand version of this
String str1 = new String("dave");
String str2 = new String("dave");
So str1 and str2 are different objects and may be modified separately as such
"dave", the original string, exists once only in memory, with another reference.

Is it possible to change a variables value from an array

This is a little confusing question for me to express, but I'll do my best.
So:
ArrayList<Object> fieldList = new ArrayList<Object>();
I then dump a lot of different variables to this array:
fieldList.add(objectsURL); //string
fieldList.add(X); //int
fieldList.add(Y); //int
...
If I change the variable, the values in the array change
too-confirming the array stores a reference to the memory, rather
then value itself.
However, if I then retrieve data from the array then set that...
Object object = ((String)this.fieldList.get(0));
Then set object
object = "meeep!"
objectsURL is not set to "meep!" but rather it retains its original
value.
I assume this is because the "object" is not referencing the original
variable anymore, that instead its pointing to a new immutable string
in the memory.
All expected Java behavior I think....but then, how would I go about
setting the actual original variable? is this possible in java?.
So, in other words. Given only access to "fieldList" is it possible to change the value of
"objectsURL"?
So, if:
String objectsURL = "www.google.com"
fieldList.add(objectsURL);
Is there a way to set objectsURL to "www.stackoverflow.com" using only a reference from fieldList?
I dont want to change the fact that fieldList contains "objectsURL", I want to change what string the variable "objectsURL" actualy contains.
If not, is there an alternative method to achieve the same thing?
I hope my question explains the problem well enough.
My use-case is trying to make a serialization/
deserialization system for a bunch of my objects. I was hoping to put
all the fields into a arraylist I could retrieve for both reading and
writing....thus avoiding having to hard-code long lists of
field[0]=blah and blah=field[0] and then going though constant pains
of needing to renumber them each time I add a new field before
another.
(I cant use Javas inbuilt serialization, as I am using GWT and this is client side only.)
Thanks,
I assume this is because the "object" is not referencing the original variable anymore, that instead its pointing to a new immutable string in the memory.
Correct, each time you use the assignment operator = on an object you change the object it refers to, not the object itself.
To change the values in the List, you use the .set method of an ArrayList
this.fieldList.set(0, newValue);
Since your variable is a String, there is no way you can change the String-variable through the list
Your alternatives:
using a char-array
List myList = new ArrayList();
char[] charArray = "My String".toCharArray();
myList.add(charArray);
charArray[0] = 'A';
String theString = new String(myList.get(0)); // "Ay String"
If you use a char-array, make sure that the length of the array is enough to contain the number of characters you want to have in the future, because to change the length of the array you will need to create a new array (array lists can be expanded dynamically, arrays can not)
Embed the String inside your own class (I have ignored getters and setters here)
class MyString {
public String value;
public MyString(String value) {
this.value = value;
}
}
MyString myStr = new MyString("some value");
list.add(myStr);
((MyString) list.get(0)).value = "a new value";
System.out.println(myStr.value); // will print "a new value"
Strings are immutable, so it is impossible to change the contents of a String object. Also, you cannot use the list to change what object the reference variable objectsURL points to. To achieve what you want, you will need to create a custom class that has a String member. You can then store instances of this class in a List and change the String references to via the references in the list. The changes will then be reflected in any other reference variables which refer to the objects in the list.
First, you declare a variable 'object' and assign some Object out of the ArrayList. Later you assign some other object "meeep!" to this variable. There is no reason that your 'object' variable is related to the ArrayList.

Object Creation JAVA [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between “text” and new String(“text”) in Java?
Please explain the brief and detailed difference between following 2 statements:
String a= "somevalue";
String b = new String("somevalue");
I know that 2nd statement creates and provide memory to String Object b in heap. But why object a doesn't get memory and its still allowed to operate on string methods.
a and b are references to Objects, not Objects.
When you do a = b; it doesn't copy the Object, it copies a reference to an Object.
A String has a char[] inside it which is another object.
a gets an reference to an existing object so it may not need any extra memory.
b get a reference to a newly created object so that requires more memory.
its still allowed to operate on string methods.
This has nothing to do with how the object was created.
The first affects the literal String object "somvalue" to variable a. This literal String object is cached in a pool, as all literal Strings.
The second creates a new instance of empty String. Since String instances are immutable, it's equivalent to String b = "";, except it instantiates a new object for nothing.

Assign a String content to a new String in Java from parameter

Having this method
void doSomething(String input)
{
//trick for create new object instead of reference assignment
String workStr= "" + input;
//work with workStr
}
Which is the java way for doing that?
Edit
if I use input variable as input=something then Netbeans warns about assigning a value
to a method parameter
If I create it with new String(input) it warns about using String constructor
Perhaps the solution is not to assign nothing to input, or just ignore the warning..
String copy = new String(original);
Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#String(java.lang.String)
Strings in java are immutable, which means you cannot change the object itself (any operation returning a string (e.g. substring) will return a new one).
This means there is no need to create a new object for Strings, as there is no way for you to modify the original. Any attempt to do so will just result in wasted memory.
Assigning references is only a problem when the objects in question are mutable, because changes in one object will reflect in all other copies of the same reference.

Categories