• Post Reply Bookmark Topic Watch Topic
  • New Topic

Is my parameter immutable?  RSS feed

 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello.

I have next code:



Thank you.
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 66304
152
IntelliJ IDE Java jQuery Mac Mac OS X
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What happened when you tried it?
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right. I should have tried it before posting. It's a part of my big class and I didn't realise that I can check it quite easy.
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 66304
152
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well done! What did you discover?
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's immutable even if I pass array directly. I don't know why though. I read that all object arguments in Java pass by address, not by value.
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's immutable even if I pass array directly. 

Can you post the code you used to test with that shows it's immutable?
 
Paul Clapham
Sheriff
Posts: 22823
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Aleksey Movchan wrote:I read that all object arguments in Java pass by address, not by value.


Unfortunately that's not true. All arguments in Java are passed by value, i.e. a copy of the parameter is given to the method. However you don't seem to be distinguishing between a reference variable and the object its reference points to. It's the reference which is copied (so the parameter in the method refers to the same object as the reference in the calling code). There is no general concept of copying an object in Java and there is nowhere that objects will automatically be copied. Of course you can write your own code which copies an object but in the general case that's not an easy thing to do/

So when you're talking about "immutable" it isn't clear whether you're talking about the ability to change the reference to an object or the ability to change an object (i.e. to change its internal state). The concept of "immutable" is different for variables than it is for objects; an immutable variable is one which can't be assigned a different value, whereas an immutable object is one whose internal state can't be changed.

In the case of using an array as a method parameter, what the method actually receives is a reference to an array. This is a copy of a reference to the same array which the calling code used as the parameter. Remember, no copying of objects takes place, so both references point to the same array. And arrays aren't immutable.
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's a bit messy, but here it is:

 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the output from when your test code is executed that shows what you are talking about?
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder wrote:What is the output from when your test code is executed that shows what you are talking about?


parent: [1, 2, 3, 4]
twin: [100, 2, 3, 4]

Despite I'm passing instance variable arr[] as an argument when creating twin array, it's not changed by set() method when I'm using twin.set() for twin array.
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One fault with the print out is that the contents of the array was changed in the twin method AFTER the parent array's contents was printed.
A better test needs to print the parent array value AFTER the array was changed following the twin line.


A problem with the posted code is the lack of comments saying what the code is doing.
For example the Board constructor's should have a comment saying it is making a local copy of the contents of the array that was passed to it.
 
Carey Brown
Saloon Keeper
Posts: 3310
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your class has a reference to an array, though the instance itself is not changing the contents of the array it's referencing is changing. If you want an immutable class you'll have to make a private copy of the array elements for each instance of your class.
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder wrote:One fault with the print out is that the contents of the array was changed in the twin method AFTER the parent array's contents was printed.
A better test needs to print the parent array value AFTER the array was changed following the twin line.


No, it's not. I can print arr[] variable exactly after I use twin.set(), it's still not changed.

A problem with the posted code is the lack of comments saying what the code is doing.


The task is when I have some class with instance variable arr[] (it takes arr[] in constructor), to return twin of this class with changed instance variable. But we can't change initial instance variable.
Possible solutions:
1. MyClass twin = new MyClass(arr);
OR
2. MyClass twin = new MyClass(Arrays.copyOf(arr));

I thought 1 example wouldn't work. But it's working and returning changed copy of my initial array (not refference).
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
btw guys how can I edit my posts? As I can see it's possible, but I can't find a button
 
Norm Radder
Rancher
Posts: 2240
28
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You missed this part of my post:
the Board constructor's should have a comment saying it is making a local copy of the contents of the array that was passed to it.


In your test program there are 3 arrays:  one in main, one in the Board created on line 30 and one in the Board created on line 21.  The set method changes the last array from line 21.
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder wrote:In your test program there are 3 arrays:  one in main, one in the Board created on line 30 and one in the Board created on line 21.  The set method changes the last array from line 21.


Yeah, but why is it not changing array from line 4? That is the question that bothers me.
 
Norm Radder
Rancher
Posts: 2240
28
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
changing array from line 4

Each instance of the Board class has its own array as defined on line 4.  The set method only changes the contents of the array in the instance of Board that it is in.  The array in the other instance of Board is not changed.  If you want to change the contents of the array in the instance where the twin method is called, add a call to this.set() to the twin method. (Note the this. is not required)
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder

Just to be clear. If we pass array as an argument, we pass address refference, not the value - is this true?
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Aleksey Movchan wrote:. . . we pass address refference, not the value - is this true?
No.

You have already been told that all arguments are passed by value, never by reference. If your array is at address 0x1234abcd then a copy of that number 0x1234abcd is passed.
Imagine I told you by phone that you are to do something with information written in a book. I tell you to look on page 1234 and you write down 1234. That number 1234 is now a copy of what I told you; I also give you the book. Does that tell you whether you can write anything on page 1234? As soon as you get the book, you change what you wrote to read page 4321 (it is a big book) and look there instead. That doesn't change what I have as my copy of the page number: 1234.
If the address had been passed by valuereference(←corrected after Dave Tolls' post), then I would have given you a piece of paper with 1234 written on. When you return it, I shall have only the number 4321.
There are websites which say things like
When you pass a primitive data type, . . . then you are passing by value. . .  When you pass a Java object, . . . you are passing by reference.
...which is totally mistaken. There are also websites which correctly tell you whether Java® uses pass‑by‑reference or not, but don't seem to know what pass‑by‑value means.
 
Dave Tolls
Ranch Foreman
Posts: 3056
37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
If the address had been passed by value reference, then I would have given you a piece of paper with 1234 written on. When you return it, I shall have only the number 4321.


I think you mean 'refarence'.
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:. . . I think you mean 'refarence'.
Yes, you are right. My apologies. Shall change it.
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Aleksey Movchan wrote:. . . we pass address refference, not the value - is this true?
No.
You have already been told that all arguments are passed by value, never by reference.


It was my problem with terminology in the first place
When I said "we pass address refference" I meant exactly 0x1234abcd from your example for objects. So it's a value in this example, I got it, thank you.
 
Rob Spoor
Sheriff
Posts: 21133
87
Chrome Eclipse IDE Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Aleksey Movchan wrote:

That can actually be shortened, because each array has a clone() method that has a covariant return type of the actual array type (so for int[] it's int[], for String[] it's String[], etc):
 
Aleksey Movchan
Ranch Hand
Posts: 49
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder wrote:
Each instance of the Board class has its own array as defined on line 4. 


In my language one of the meanings of word "green" is a novice. Like a small plant which is green. So 3 months ago a was too green to understand what you said And only you noticed this part of the code. I really created 3rd array in my constructor, worked with it and didn't understand why the hell if I'm passing a value of array refference I can't change my parent array. Thank you.
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!