Reputation: 18024
I have a class,
class MyClass {
private int val;
public static final MyClass myObject = new MyClass(1);
MyClass(int a){
val = a;
}
public int getVal(){
return val;
}
public MyClass func1(){
MyClass temp = myObject;
temp.val = 2;
return temp;
}
public static void main(String [] args){
MyClass x = new MyClass(4);
System.out.println(myObject.getVal());
x.func1();
System.out.println(myObject.getVal());
}
}
It prints:
1
2
I was expecting it to print:
1
1
There seems to be a fundamental misunderstanding on my part. I was expecting that myObject
being a final static
value cannot be changed, and when I do MyClass temp = myObject
, I create a new object called temp
of type MyClass
and assign the value of myObject
to this newly created object. Please correct me if I am wrong. It seems that the there is no new object created and temp
simply points to the original myObject
EDIT: Thanks for the answers! I now understand that the =
operator never makes a copy of the object, it just copies the reference. What I need is to make a copy of myObject
and store it in temp
. What would be the best way to achieve this?
EDIT2: Another strange behavoir or a feature of Java?
I modified the code slightly
class MyClass {
private Integer val;
public static final MyClass myObject = new MyClass(1);
MyClass(int a){
val = a;
}
public int getVal(){
return val;
}
public MyClass func1(){
MyClass temp = new MyClass(33);
temp.val = myObject.val;
temp.val = 2;
return temp;
}
public static void main(String [] args){
MyClass x = new MyClass(4);
System.out.println(myObject.getVal());
MyClass y = x.func1();
System.out.println(x.getVal());
System.out.println(y.getVal());
System.out.println(myObject.getVal());
}
}
output is
1
4
2
1
Therefore, when I create temp
using new MyClass(33)
and then set temp.val = 2
, it actually makes a copy of val. In other words, temp.val
does not point to myObject.val
. Why is this so?
Upvotes: 3
Views: 1754
Reputation: 12368
Definition of the modifier final states that the object reference cannot be changed. In the first code snippet
public static final MyClass myObject = new MyClass(1);
myObject is a final reference which is pointing to a object with val =1. However this does not imply that the contents of the object cannot be changed. the function func1() gets a reference on the object with value 1 and changes its val to 2. thereby it is perfectly legal.
For the second snippet
public MyClass func1(){
MyClass temp = new MyClass(33);
temp.val = myObject.val;
temp.val = 2;
return temp;
}
public static void main(String [] args){
MyClass x = new MyClass(4); //line A
System.out.println(myObject.getVal()); //returns 1
MyClass y = x.func1(); //line B
System.out.println(x.getVal()); //line C
System.out.println(y.getVal()); //line D
System.out.println(myObject.getVal());
}
At line A obj with val 4 is created.
At line B func1 is called which in summary creates a new object with val=33 which is then changed to val=1 and then val=2.
At line C we get output 4 from the obj created at line A.
At line D we get output 2 from the changes we made in using line B.
At line E we get output 1 from the static final object which is not changed.
Upvotes: 0
Reputation: 55464
MyClass temp = myObject;
That's not creating a new instance, it's just assigning the reference so that temp points to the same instance as myObject.
So your statement:
I create a new object called temp of type MyClass
is incorrect, as you aren't creating a new object here, just assigning an object reference.
EDIT
If your goal is to make a copy of myObject and return it from func1()
, then you could do this (by copy I assume you mean copying the val
value as well, if you want to use a different value for val
then you can adjust this code accordingly):
public MyClass func1(){
MyClass temp = new MyClass(myObject.getVal());
return temp;
}
Upvotes: 7
Reputation: 5335
After reading the posted answers:
If you want the temp reference variable to hold a ref. to an immutable object you can make your class immutable.
You can find more information on how to do that here:
http://www.javapractices.com/topic/TopicAction.do?Id=29
or
http://java.sun.com/docs/books/tutorial/essential/concurrency/imstrat.html
Upvotes: 1
Reputation: 70564
In Java, the =
operator assigns references, not objects like in C++.
A final field can only be assigned once. That does not mean that objects reachable through a final field can not be modified.
Put differently: Unlike C++'s const
, final
only protects the reference, not the object.
Upvotes: 1
Reputation: 39485
The field is final
, which means that you cannot reassign the field. Your myObject
var, however, is not immutable. When you call func1()
on your myObject
, you are changing myObject.val
to 2.
Upvotes: 5
Reputation: 5581
You are obtaining a reference to an instance of the MyClass object and modifying one of its members. That reference is not immutable; only the field named myObj is immutable.
Upvotes: 2
Reputation: 8722
I think you have kinda answered your own question. You are correct in saying that there isn't really a new object created by the line MyClass temp = myObject;
temp is only an object reference to your static instance of myClass.
You can check this by modifying the code as so.
public MyClass func1(){
MyClass temp = myObject;
System.out.println(myObject == temp);//print true
temp.val = 2;
return temp;
}
Upvotes: 1