Reputation: 2417
I have declared a String variable in Kotlin as like.
var str: String
The Kotlin document contradict for mutability concept. As per document... var is mutable.
But for String it define as immutable.
So please clarify contradiction...
Upvotes: 13
Views: 9065
Reputation: 325
Personally, I find it easier to think about the difference between val
and var
in terms of Java. val
would correspond to a variable with the final
modifier, which means it can only be assigned once and var
is just with that modifier absent and therefore reassignable.
The object themselves can still be either mutable or immutable. Mutability here refers to the variable itself.
Upvotes: 1
Reputation: 2970
Actually, String variable
is mutable, but String Value
is Immutable.
Appreciate with @cricket_007
Let me Describe deeply what happened behind When you declare variable.
val string1 = "abcd"
val string2 = "abcd"
As Shown above image and Declaration.
-String pool is a special storage area in The Heap Memory.
-When a string is created
and if the string already exists
in the pool, the reference of the existing string will be returned
, instead of creating a new object and returning its reference.
-If string is not immutable, changing the string with one reference will lead to the wrong value for the other references.
-Now with above our example Value Assign to Variable String1 now we can use this variable.
also we can change the value
string1.renameTo("Hi This Is Test")
So What happen at behind in memory ?
->yes,
if "Hi This Is Test" this string available it will return a reference to "string1"
else it Create new space and give reference To "string1"
Actually, that's Why String called immutable.
Reference - Link
Upvotes: 12
Reputation: 7411
An excellent example by @Frank. It makes me more clear, what the documentation said.
The first part of the documentation says:
Classes in Kotlin can have properties. These can be declared as mutable, using the var keyword or read-only using the val keyword.
Now, the second part says:
Strings are represented by the type String. Strings are immutable.
These both are true in my opinion.
Based on the Frank's example, let's take another example.
data class User(var name: String, var email:String)
var user1 = User("Foo","[email protected]")
// user1 is mutable and object properties as well
val user2 = User("Bar","[email protected]")
// user2 is immutable but object's properties are mutable
Now, consider property user1
. It is mutable as it is declared with keyword var
. And also the User object assign to it.
But the user2
property is immutable. You can not change the assigned object to it. But the Object itself has mutable properties. So the properties can be changes by user2.name = "Foo"
.
Now changing the example a bit and making user properties immutable.
data class User(val name: String, val email:String)
var user1 = User("Foo","[email protected]")
// user1 is mutable and object properties are not
val user2 = User("Bar","[email protected]")
// user2 is immutable and object's properties are also immutable
Here, User's properties are immutable. So, user1
is mutable, you can assign another object to it. But the properties are immutable. So user1 = User("New Foo","[email protected]")
will work. But after assigning an object User, you can not change it's properties, as they are immutable.
Now, let's take an example with String type.
var str1 = "Bar"
// Here str1 (property) is mutable. So you can assign a different string to it.
// But you can not modify the String object directly.
str1 = "Foo" // This will work
str1[0] = 'B' // This will NOT work as The string object assigned to str1 is immutable
val str2 = "Foo"
// Here both str2 and the assigned object are immutable. (Just like Java final)
And as the Frank said,
just because a symbol is declared a val does not make the object it points to immutable.
My final cents:
String object is immutable, as it can not be changed. But that immutable String object can be assigned to a mutable property, which can be re-assigned with the different String Object. That is what
var
keyword does. Making the property mutable. But the object it points to can be mutable or immutable.
Upvotes: 3
Reputation: 3250
I don't like way the documentation is written either but there is no contradiction in reality. They are using the word mutable in a way that invites a comparison between program symbols and objects that is not very helpful.
A variable declared by the var
keyword is reassignable whereas one declared with the val
keyword is not.
A string is an immutable object type, once created it cannot be changed.
Whether a variable is reassignable and whether the object it points to is immutable are two different things.
Here's an example:
class Person(var name: String)
val fred = Person("Fred")
fred.name = "Barry" // fred is not immutable
fred = Person("Barry") // ERROR Val cannot be reassigned
So to use mutable in the way the documentation does, just because a symbol is declared a val
does not make the object it points to immutable.
Upvotes: 8
Reputation: 33749
In Kotlin/Java an object's behaviour does not depend on the kind of reference you use to access it. Everything is (potentially) in the heap, so any property is just a reference (a.k.a. link) to the object.
val str = "Hello"
val a = str
var b = str
In the snippet above there is only one immutable string str
, and both a
and b
reference it. You can't change the string, no matter what reference you use, mutable or immutable. But you can change the mutable reference itself to point to another (immutable) string:
b = "World"
Upvotes: 0
Reputation: 191701
What's the contradiction? A string is read-only. Just as Java, you cannot set a[i] = 'x'
, any string replacement methods return new strings, etc. Therefore, not mutable. This point is made to clarify the functionality of a var
String type
The difference between var and val can be associated with a final
variable in Java. You can make a final String
constant, or you can have a regular String
object
Upvotes: 3