what do we mean exactly when we say "ints are immutable" - java

I'm confused on the concept of "being immutable". Our professor is saying "ints are immutable! Strings are immutable" everyday, what does he mean by that exactly?
A more general question, how do we know if a data structure is immutable or not?
Thanks

Some of the other answers here are confusing mutability/immutability with value/reference semantics, so be careful...
Simply put, an entity is mutable if it may be modified after it's been created. In other words, its value may change over time.
First, a counterexample. A Java String object is immutable; there is no method that you can call on a String object that will change its value:
String a = "foo";
a.concat("bar");
System.out.println(a); // foo
You could do this instead:
String a = "foo";
a = a.concat("bar");
System.out.println(a); // foobar
but that works because concat() is creating a new String object, and the reference a is then repointed at it. There are now two String objects; the original has not changed (it's just lost forever). a is mutable, the underlying object isn't.
As for int variables; in C or Java, we can do this:
int x = 3;
x = 4; // Mutates x
x++; // Mutates x
How do we know these really mutate x, rather than simply creating a new integer "object" and "repointing" x at it? (Other than by the fact that the language assures us that primitive types are distinct from object types.) In C, we can somewhat prove it:
int x = 3;
int *p = x; // Pointer to original entity
x = 4;
printf("%d\n", *p); // 4
AFAIK, there is no equivalent approach in Java. So you could argue that the question of whether integer types are truly mutable in Java is irrelevant.
As for how we know whether a given type is immutable, very often we don't. At least, not without inspecting it, or simply believing a promise we've been told.
In Java, ensuring a user-defined type is immutable involves following a few simple rules (explained here). But it's still just a promise; the language doesn't enforce it.

Immutability (of an object or value, not a variable) usually means there's no way to do an in-place change of the value. (One that would propagate to other references to it.) This means that if you have something like the following:
String a = "foo";
There is no operation that you could perform on a that would change its value. I.e. you can't have a hypothetical method append() that would cause the following behaviour:
String a = "foo";
a.append("bar"); // a is not reassigned
System.out.println(a); // prints "foobar"
You can contrast this with mutable objects like collections:
int[] as = new String[] { "foo" };
as[0] = "bar"; // we're changing `as` in-place - not the Strings stored in it
System.out.println(as[0]); // prints "bar"
Primitive types are not a great choice of example for Java, since you can't have multiple references to them, and there's no way to demonstrate the distinction between a mutation and a reassignment.

It's awkward to talk about immutability of ints, because the idea of mutating something that isn't a container doesn't make sense to most of us. So let's talk about strings.
Here's a string, in Python:
s = "abc"
Strings are containers in the sense that they contain some number of individual characters: here a, b, and c. If I want to change the second character to a d, I might try:
s[1] = 'd'
Which will fail with a TypeError. We say strings are immutable in Python because there is no operation that will alter an existing string. Certainly there are plenty of operations that will perform some operation and create a new string, but existing strings are set in stone.
There are a couple advantages here. One is that it allows interning: sometimes when a string needs allocating (and at the discretion of the interpreter), CPython will notice that an identical string has already been allocated and just reuse the same str object. This is easiest when strings are immutable—otherwise, you'd have to do something about problems like this:
s = "abc"
t = "abc" # this reuses the same memory, as an optimization
s[0] = "x" # oops! now t has changed, too!
Interning is particularly useful in Python and similar languages that support runtime reflection: it has to know the name of every function and method at runtime, and a great many methods have builtin names like __init__ (the name of the constructor method), so reusing the same string object for all those identical names saves a good deal of wasted space.
The other advantage is in semantics: you can safely pass strings to arbitrary functions without worrying that they'll be changed in-place behind your back. Functional programmers appreciate this kind of thing.
The disadvantage, of course, is that doing a lot of work with very large strings requires reallocating and rebuilding those large strings many times over, instead of making small edits in-place.
Now, about ints. This is NOT an example of immutability:
x = 3
x = 4
This doesn't involve the actual objects at all; it only assigns a new value to the variable x.
Consider instead:
x = [1, 2, 3]
y = x
x[:] = [4, 5, 6]
print y # [4, 5, 6]
The x[:] = syntax is "slice notation" for replacing the entire contents of a list. Here, x and y are two names for the same list. So when you replace the contents of x, you also see the same effect in y, because... they both name the same list. (This is different from reference variables in other languages: you can assign a new value to either x or y without affecting the other.)
Consider this with numbers. If you could do some hypothetical operation like the above on plain numbers, this would happen:
x = 3
y = x
x[:] = 4
print y # hypothetically, 4
But you can't do that. You can't change the number an existing int represents. So we call them immutable.
Mutating an int is easy in Smalltalk:
3 become: 4
This would change the 3 to a 4, overwriting the memory that previously contained a 3. If ints are interned (as they can be in Python), this could even mean that everywhere 3 appears in your source code, it acts like the number 4.
In C, these distinctions aren't as meaningful, because variables are fixed blocks of memory rather than the transient labels of Python. So when you do this:
int x = 3;
x = 4;
It's hard to say definitively whether this is "mutating" an int. It does overwrite existing memory, but that's also just how C variable assignment works.
Anyway! Mutability is just about whether you're altering an existing object or replacing it with a new one. In Python and Java, you can't alter existing strings, and you can't "alter" numbers, so we call them immutable. You're free to change the contents of lists and arrays in-place without creating new ones, so they're mutable.

What is immutable is highly language-dependent, but an immutable object is simply an object that cannot be changed after it is created.
What this usually means is that:
int x = 4;
x = 5;//not 'allowed'
This is seen in languages where primitives, such as an int, can be immutable (such as functional languages like Scala).
Most objects in OOP are actually pointers to a place in memory. If that object is immutable that location in memory cannot have its contents changed. In the case of a String in Java, we see this happening:
String a = "Hello"; //points to some memory location, lets say '0x00001'
a = a + " World!"; //points to a new locations, lets say '0x00002'
System.out.println(a);//prints the contents of memory location '0x00002'
In this case, a actually points to an entirely different place in memory after line 2. What this means is that another thread with a different scope that has handed a would not see "Hello World!" but instead "Hello":
String a = "Hello";
startThread(a, " Hello!");//starts some thread and passes a to it
startThread(b, " World!");//starts another thread and passes a to it
...
public void methodInThread(String a, String b) {
a = a + b;
System.out.println(a);
}
These two threads will output the following, regardless of the order they're called in:
"Hello Hello!" //thread 1
"Hello World!" //thread 2

An object is considered immutable if its state cannot change after it is constructed.
source : http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

Typically it means you can't call a method on the type (int or whatever) that will change a
Sometimes people refer to value types as being immutable
//theres no way for this to be mutable but this is an example of a value type
int a = 5
int b = a;
b=9
a does not change unlike class types like
MyClass a = new MyClass
MyClass b = a
b.DoSomething()
//a is now changed

An immutable object is some thing that once instantiated can not be modified. If you have to modify, a new object will be created and pointed to the reference.
And ints are not immutable.

There are some classes in java which are immutable like String, All Wrapper Class ie. Integer, Float, Long etc.
For Example:
Integer i=5;
i=10;
i=15;
When Integer i=5, here a new Integer object is created, then in the 2nd, i=10 rather assigning this value 10 to previously created object, a another new object is created and assign to i, and 3rd i=15 , here again new object is created and again is assigned to i.
Note: don't be confused with int with Integer. int is primitive type and Integer is wrapper class. All primitives are mutable.

The concepts of mutability and immutability are only relevant for things to which code may hold a reference. If one holds a reference to something, and some immutable aspect of that thing's state is observed to have some value (or state), then as long as that reference exists, that aspect of the thing's state may always be observed to have the same value (state).
The String type in Java may reasonably be described as immutable, because code which has a reference to a string and observes that it contains the characters "Hello" may examine it at any time and will always observe that it contain those characters. By contrast, a Char[] might in one moment be observed to contain the letters "Hello" but at some later time be observed to contain the letters "Jello". Thus, a Char[] is considered mutable.
Because it is not possible to hold a direct reference to an int in Java, the concepts of mutability and immutability are not really applicable to that type. One can, however, hold a reference to an Integer, for which they are relevant. Any such reference that is observed to have a particular value will always have that same value. Thus, Integer is immutable. Note that while the concepts of mutability and immutability aren't really applicable to value types like int, they do share a useful aspect of immutable types: the state represented by a storage location (variable, field, or array element) of either a primitive type or an immutable type is guaranteed not to change except by overwriting that location with either a new value or a reference to a different immutable object.

Related

Can anyone explain me what is state and mutable data?

In computer science, functional programming is a programming paradigm
that treats computation as the evaluation of mathematical functions
and avoids state and mutable data.
http://en.wikipedia.org/wiki/Functional_programming
Can anyone explain me what is state and mutable data? Can anyone give me examples in either JAVA or JavaScript.
mutable suggest anything that can change, i.e. an int
int a = 0;
System.out.prtinln(a); //prints 0
a = 2;
System.out.prtinln(a); //now prints 2, so its mutable
In java a string is immutable. you cannot change the string value only its reference.
String s1 = "Hello";
System.out.println(s1); //prints Hello
String s2 = s1;
s1 = "Hi";
System.out.println(s2); //prints "Hello" and not "Hi"
State is something which an instance of a class will have (an Object).
If an Object has certain values for its attributes its in a diffrent state then another Object of the same class with diffrent attribute values
State refers collectively to the data stored in the object that determines the current properties of the object. For example, if you have a BankAccount object, the owner of the account and the amount of money in it represent the state of the account.
However, not all state is bad for functional programming, only the mutable+ one is not acceptable. For example, the characters of which a string is composed is that string's state. If you cannot change the content of the string, it is said to have an immutable state. This fits well with functional programming paradigm.
+ mutable is a fancy word for "changeable".
Mutable state is everything that can make a function return a different value, despite it being called with the same arguments.
Simple example in Java:
public static double badSqrt(double x) {
double r = Math.sqrt(x);
if (System.currentTimeMillis() % 42L == 0L) return r;
return r + 0.000000001;
}
This function computes a slightly incorrect result sometimes. We say that badSqrt is impure, because its result does not solely depend on its argument (and constants).
For the person debugging a program that contains calls to badSqrt() or impure functions in general this is a nightmare. Often, the program seems to work, but once in a while, wrong results are delivered. Unless the function is clearly documented or the source code is available, it'll be hard to track the bug.
In such cases, it is said that the behaviour of the functions depends on mutable state. This is state that could be changed (mutated) by completely unrelated parts of the program, or, like in the example, by another program (the operating system).
A classic example of an immutable object is an instance of the Java String class.
String s = “ABC”;
s.toLowerCase();
System.out.println(s);
Output = ABC
This is because s continues referencing its immutable String. If you want to mutate s, a different approach is needed:
s = s.toLowerCase();
This will create a new reference. Now the String s references a new String object that contains "abc".
suppose
int i=5;
now the state of variable i is that , now it has contained value 5.
suppose now i have set i=7;
now the state of variable i is that , now it has contained value 7, it has replaces 5.
if change in value is possible then it is called as-mutable that means
we can change state here.
if change in value is not possible then it is called as-immutable.
Here's the simplest explanation of the difference between state and mutable state. Almost every language has built in methods and functions that we can call to do different things. These methods and functions maintain its own state and we can manipulate it depending on the parameter(s) we use. Different parameters gives different parameters(arguments) can return different values. Now, lets say we make a constructor(JavaScript) to store our own state. We then write a function to manipulate state based on user input, and after we write it we don't change the parameter(s), even when it's called. BUT the content inside state can be changed using setState, resulting in endless changes from the same function without changing the parameter(s).
State data is static. I.e. hypercard. Mutable data resembles more of a binary assembled artificial movement paradigm. QED -Bryan Meluch Purdue 1997 [verb.atim] Web

rely on java String copy on write

My application creates a lot of instances of a class, say class A. All instance contains a string, and most of them contain the same String
class A {
String myString;
}
I know that JVM makes "all equal strings" point to the same String that is stored just one time. If myString field of one of my A instances is overwritten, the reference to the original string is replaced by the reference to the new String value and all works as expected, that is as if each instance had a copy of the string all for itself.
Is this behaviour required to a compliant JVM, or is it a sort of improvement of the jvm that may change from a jvm to another, or from version to version?
Another way to put the question: when designing higly redundant (string based) data-structures, should one rely only on the copy on write mechanism or it is adviceable to put in place something at the application level?
Another aspect of this is that your Strings will not be the same if they are created dynamically (e.g. allocated by parser). Check out String.intern() if space is a concern:
String a = String.valueOf('a') + "b";
String b = a.intern();
String c = "ab";
// now b == c is true
as #Hot Licks said: strings are immutable so there is no place to talk about copy on write. also when you are using mutable object you have to be aware that 'copy on write' may not be available on your client's environment.
and another thing that may be very important when you create a lot of objects. each object contains a few bytes of header, pointers etc. if i remember correctly empty object is like 20 bytes or so. when you we are talking about a lot of objects containing properties it starts to be significant. be aware of that and when you measure that it is causing the problem then you have to do something at the application level (lightweight design pattern, using stream xml parser etc).
The fact is that String are regular objects.
String a = "test";
String b = a;
Does exactly the same thing as:
StringBuffer a = new StringBuffer("test");
StringBuffer b = a;
that is: in both cases, b is a second reference to a, and this is not due to the immutability.
Immutability comes into play
So, you always handle two pointers to the same data. Now, if the class is immutable, you can forget about it: nobody will change your data under your shoes not because you have a copy for your own, but because the shared copy is immutable. You can even think that you have a copy of the string, but actually a copy has never existed since String b = a; does what it does for each object: a copy of the only reference.

Is it possible to swap two variables in Java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to write swap method in Java?
Given two values x and y, I want to pass them into another function, swap their value and view the result. Is this possible in Java?
Not with primitive types (int, long, char, etc). Java passes stuff by value, which means the variable your function gets passed is a copy of the original, and any changes you make to the copy won't affect the original.
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
// a and b are copies of the original values.
// The changes we made here won't be visible to the caller.
}
Now, objects are a bit different, in that the "value" of an object variable is actually a reference to an object -- and copying the reference makes it point at the exact same object.
class IntHolder { public int value = 0; }
void swap(IntHolder a, IntHolder b)
{
// Although a and b are copies, they are copies *of a reference*.
// That means they point at the same object as in the caller,
// and changes made to the object will be visible in both places.
int temp = a.value;
a.value = b.value;
b.value = temp;
}
Limitation being, you still can't modify the values of a or b themselves (that is, you can't point them at different objects) in any way that the caller can see. But you can swap the contents of the objects they refer to.
BTW, the above is rather hideous from an OOP perspective. It's just an example. Don't do it.
I'm going to be reallllyyyy annoying and pedantic here because the word "value" has a very specific meaning in Java, which people often don't often understand, especially when the variables hold references to objects.
I am going to assume the question asks for this behavior:
x = initialValueForX;
y = initialValueForY;
swap(x, y);
// x now holds initialValueForY;
// y now holds initialValueForX;
This is not possible because Java passes all arguments to methods by value. You can never change the actual value stored inside of x and y this way.
You can, however, if x and y hold references to objects, change the properties of the two objects in such a way as to make the printed values look like each other's initial values:
x = initialValueForX;
y = initialValueForY;
swap(x, y);
System.out.println(x); prints what looks like initialValueForY
System.out.println(y); prints what looks like initialValueForX
This works if your understanding of value is what the object looks like, rather than what the identity of an object is. Usually, that is acceptable.
(Was going to give a good example here, but cHao already did. Plus others pointed out that this was a duplicate question anyway.)

String initialization difference

Firstly apologies if this a very basic question, I'm just curious to know the difference between the following string definitions
String x= "hello";
String y = new String("hello");
I knew that in java String is a Class its neither a primitive nor a Wrapper(Correct me if this a misconception). Consider a class A, I've seen the following declarations for any class so far. i think A c; is valid and A a = new A(); is also valid. I'm confused with A a ="xyz"; this is how we declared a String as in above first type of definition. I'm sure that the above two definitions are absolutely different, like if i say x==y it returns false. I understand that y is the reference to the String object. What is x there, how is it stored in memory, interestingly i found that both x and y can access all the methods of String class.
Then what is the advantage of one over other.Can i know the applicability of each.
From the 2nd edition of Joshua Bloch's "Effective Java":
String s = new String("stringette");// DON'T DO THIS!
The statement creates a new String instance each time it is executed,
and none of those object creations is necessary. The argument to the
String constructor ("stringette") is itself a String instance,
functionally identical to all of the objects created by the
constructor. If this usage occurs in a loop or in a frequently invoked
method, millions of String instances can be created needlessly. The
improved version is simply the following:
String s = "stringette";
The first couple of answers you got are incorrect. There is a difference between the two statements. But first, the TL;DR version: Use String x = "hello"; in 99.99999% of situations.
The full answer:
The chief difference between those two is that in the first case, the string is implicitly interned; in the second case, it is not. This is a very real difference, although it only comes into play in select situations. So in the first case, if you have any other strings with the same series of characters ("hello"), your x will refer to the one shared object that is used in all of those places (this is useful, since String instances are immutable). In the second case, you're explicitly saying you need (for whatever reason) to have a String instance with that sequence of characters which is separate from any others. There are very, very few reasons to do that.
With regard to x==y, in Java you compare strings for equality using equals, not ==. The == operator when used with object references compares the references (e.g., do both variables point to the same object), not the object contents.
So: Prefer the first form to the second unless you have a good reason for doing the second.
String a = "hello"; //this kind of declaration always return "singlton" instance.
String b = "hello";
String c = new String("hello"); //This kind of declaration always return a new instance.
SO
a ==b;
but
a !=c
Very simply, the value of x is a String. A normal java.lang.String.
You're used to the idea that there are literals for primitive types (like, 7, or 3.14159, or true, or 'q'), but it seems what you may not have realised is that there are literal forms for some object types too. The only ones i can think of are java.lang.String, where you can write "hello", and java.lang.Class, where you can write SomeClass.class.
I understand that y is the reference to the String object. What is x there[...]?
Both x and y are references to String objects. The x is a reference to an interned string (as T.J. Crowder already wrote in his answer), the y is a reference to a second String object with the same content. This means:
x == y --> false
x.equals(y) --> true
y.equals(x) --> true
Then what is the advantage of one over other.Can i know the applicability of each.
Always use the first, direct version. The only valid exception which I ever encountered and found to be valid is test code which explicitly want to make sure, that the code to be tested does not use == for string comparisons but uses the proper x.equals(y) method.
One more way to initialize String is
String str =("abc");
It seems at first that this would give an error (because of the brackets) but this doesn't. Surprisingly.

Object type in java

I learnt that Java is not a 100% OOP language and that this is because of data types which are not objects. But according to me, int is of type Integer and Integer belongs to Number and Number belongs to Object. So java is a 100% OOP language. Am I correct?
No, int and Integer are different. Integer is a regular class, which as you know is a subclass of Number which itself is a subclass of Object. But int is a primitive type. It is not a class, so obviously not a subclass of anything; it has no methods or attributes, and generally there is nothing you can do with int itself, except declare variables of that type, e.g.
int x = 3;
Since int is not a class, the values of int variables are not objects. They have no methods or attributes or properties, and there's not much you can do with them except certain mathematical operations which are handled specially by the compiler.
Note that the Java compiler (recent versions) will automatically insert code to convert an int into an Integer, or vice-versa, where necessary. So it might look like they're the same thing when you write your program, but they are actually not. For instance, if you write
Integer y = 5;
javac translates that into
Integer y = Integer.valueOf(5);
Or
Map<Integer,Integer> m = ...;
m.put(4, 8);
int z = m.get(4);
becomes
Map<Integer,Integer> m = ...;
m.put(Integer.valueOf(4), Integer.valueOf(8));
int z = m.get(Integer.valueOf(4)).intValue();
To add to the previous answers (which I think may have missed the point a little) - yes, int and Integer are two completely different (but related) concepts - one is a primitive, the other an equivalent class. More importantly however, that distinction has absolutely no bearing whatsoever on whether Java is an object-oriented language.
Every single Java program uses objects at some point (even if it is just the String[] args parameter to your main method). As such, Java is unequivocally an object-oriented language, simply because it relies on classes as a primary means of program development. The fact that it supports non-object primative types has nothing to do with that at all.
int is not an object of the class Integer. In Java, not all the data types are objects.

Categories

Resources