How to prevent changing the value of variable The Next CEO of Stack OverflowConvert an array of primitive longs into a List of LongsIs Java “pass-by-reference” or “pass-by-value”?How do I efficiently iterate over each entry in a Java Map?Sort a Map<Key, Value> by valuesHow do I call one constructor from another in Java?How do I read / convert an InputStream into a String in Java?How do I generate random integers within a specific range in Java?How to get an enum value from a string value in Java?How do I determine whether an array contains a particular value in Java?How do I convert a String to an int in Java?How do I fix android.os.NetworkOnMainThreadException?
Physiological effects of huge anime eyes
How can I prove that a state of equilibrium is unstable?
Can this transistor (2n2222) take 6V on emitter-base? Am I reading datasheet incorrectly?
Create custom note boxes
Raspberry pi 3 B with Ubuntu 18.04 server arm64: what pi version
Why does freezing point matter when picking cooler ice packs?
Is it possible to create a QR code using text?
Compilation of a 2d array and a 1d array
Why did the Drakh emissary look so blurred in S04:E11 "Lines of Communication"?
How can I separate the number from the unit in argument?
Could you use a laser beam as a modulated carrier wave for radio signal?
Shortening a title without changing its meaning
Direct Implications Between USA and UK in Event of No-Deal Brexit
Avoiding the "not like other girls" trope?
What happens if you break a law in another country outside of that country?
Horror film about a man brought out of cryogenic suspension without a soul, around 1990
Gauss' Posthumous Publications?
What does it mean 'exit 1' for a job status after rclone sync
How seriously should I take size and weight limits of hand luggage?
Find a path from s to t using as few red nodes as possible
Does int main() need a declaration on C++?
Is the offspring between a demon and a celestial possible? If so what is it called and is it in a book somewhere?
Could a dragon use its wings to swim?
MT "will strike" & LXX "will watch carefully" (Gen 3:15)?
How to prevent changing the value of variable
The Next CEO of Stack OverflowConvert an array of primitive longs into a List of LongsIs Java “pass-by-reference” or “pass-by-value”?How do I efficiently iterate over each entry in a Java Map?Sort a Map<Key, Value> by valuesHow do I call one constructor from another in Java?How do I read / convert an InputStream into a String in Java?How do I generate random integers within a specific range in Java?How to get an enum value from a string value in Java?How do I determine whether an array contains a particular value in Java?How do I convert a String to an int in Java?How do I fix android.os.NetworkOnMainThreadException?
I am a beginner in Java. When developing a program, I created an object with a constructor with variables as arguments. But when I change the value of the variable after creating the object, my object has the second value instead of the first one. I don't want my object to change the value. What do I do?
public class Person
public Person(int[] arrayTest)
this.arrayTest = arrayTest;
public int[] getArray()
return this.arrayTest;
public boolean canHaveAsArray(int[] arrayTest)
return true;
private int[] arrayTest = new int[2];
public static void main(String[] args)
int[] array = new int[] 5, 10;
Person obj1 = new Person(array);
array[0] = 20;
System.out.println(Arrays.toString(obj1.getArray()));
My output should be [5, 10], but instead, I am getting [20,10]. I need to get [5,10] even when I change an element of the array as shown above. What should I do?
java
add a comment |
I am a beginner in Java. When developing a program, I created an object with a constructor with variables as arguments. But when I change the value of the variable after creating the object, my object has the second value instead of the first one. I don't want my object to change the value. What do I do?
public class Person
public Person(int[] arrayTest)
this.arrayTest = arrayTest;
public int[] getArray()
return this.arrayTest;
public boolean canHaveAsArray(int[] arrayTest)
return true;
private int[] arrayTest = new int[2];
public static void main(String[] args)
int[] array = new int[] 5, 10;
Person obj1 = new Person(array);
array[0] = 20;
System.out.println(Arrays.toString(obj1.getArray()));
My output should be [5, 10], but instead, I am getting [20,10]. I need to get [5,10] even when I change an element of the array as shown above. What should I do?
java
add a comment |
I am a beginner in Java. When developing a program, I created an object with a constructor with variables as arguments. But when I change the value of the variable after creating the object, my object has the second value instead of the first one. I don't want my object to change the value. What do I do?
public class Person
public Person(int[] arrayTest)
this.arrayTest = arrayTest;
public int[] getArray()
return this.arrayTest;
public boolean canHaveAsArray(int[] arrayTest)
return true;
private int[] arrayTest = new int[2];
public static void main(String[] args)
int[] array = new int[] 5, 10;
Person obj1 = new Person(array);
array[0] = 20;
System.out.println(Arrays.toString(obj1.getArray()));
My output should be [5, 10], but instead, I am getting [20,10]. I need to get [5,10] even when I change an element of the array as shown above. What should I do?
java
I am a beginner in Java. When developing a program, I created an object with a constructor with variables as arguments. But when I change the value of the variable after creating the object, my object has the second value instead of the first one. I don't want my object to change the value. What do I do?
public class Person
public Person(int[] arrayTest)
this.arrayTest = arrayTest;
public int[] getArray()
return this.arrayTest;
public boolean canHaveAsArray(int[] arrayTest)
return true;
private int[] arrayTest = new int[2];
public static void main(String[] args)
int[] array = new int[] 5, 10;
Person obj1 = new Person(array);
array[0] = 20;
System.out.println(Arrays.toString(obj1.getArray()));
My output should be [5, 10], but instead, I am getting [20,10]. I need to get [5,10] even when I change an element of the array as shown above. What should I do?
java
java
edited 2 days ago
Peter Mortensen
13.8k1987113
13.8k1987113
asked 2 days ago
OpheliaOphelia
643
643
add a comment |
add a comment |
6 Answers
6
active
oldest
votes
Array is passed by reference in Java. If you pass the original array to the constructor of Person
, you are passing the reference to the original array. So any change in arrayTest
inside Person
instance will reflect in original array(int[] array
) and vice-versa.
If you don't want to change the value of elements of original array in Person
instance then you have two options:
You can modify the code in
Person
constructor to create a copy of original array usingjava.util.Arrays.copyOf
method and then use that copy:public Person(int[] arrayTest)
this.arrayTest = java.util.Arrays.copyOf(arrayTest, arrayTest.length);Don't pass the original array to constructor, instead just send a copy of original array:
Person obj1 = new Person(java.util.Arrays.copyOf(array, array.length));
However, I would prefer first approach.
2
I agree with this answer. But from the two options stated here, First option should be the most suitable approach. The reason is, whenever you or someone else is going to use the code, they will not make the mistake mentioned in the question.
– LeoN
2 days ago
On the one hand, the first option is clearly better for the reason stated above, but the second option is useful too and should be considered. Doing what the OP accidentally did is useful in quite a few cases (although it violates some OOP principles, but I don't hold those in very high regard anyway)
– DreamConspiracy
2 days ago
add a comment |
There is no such thing as immutable (unchangeable) array in Java. The Java language does not support this, and neither does the JVM. You can't solve this at the language level.
In general, the only way to prevent changes to an array is to not share the reference to the array with other code that might change it.
In your example, you have what is known as a leaky abstraction. You are passing an array to your Person
class, and the caller is keeping a reference to that array so that it can change it. To solve this, you can:
- copy the array, and pass a reference to the copy, or
- have the constructor (or a setter for the array attribute) make the copy.
(See answer https://stackoverflow.com/a/55428214/139985 for example code.)
The second alternative is preferable from an OO perspective. The Person
class should be responsible for preserving its own internal state from interference ... if that is your design requirement. It should not rely on the caller to do this. (Even if the caller is technically part of the same class as is the case here.)
by the way, about Leaky abstraction, Joel on Software has a relevant blog article joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions
– Pac0
2 days ago
add a comment |
There is no unmodifiable array, but you can make an unmodifiable list:
List<Integer> list = List.of(5, 10);
You will have to change your code to use lists instead of arrays, but this is generally preferable anyway.
If you already have an array of a non-primitive type, you can wrap it in an unmodifiable list, like so:
List<Integer> list = Collections.unmodifiableList(Arrays.asList(array));
However, while you can't change the list directly, changing the array will change the list. Moreover, this won't work on int[]
, but only on subclasses of Object[]
.
add a comment |
Instead of passing a copy of the array to the object, as others have suggested, I would recommend that the Person object's constructor should create a copy. Which means instead of,
this.arrayTest = arrayTest;
It should be
this.arrayTest = Arrays.copyOf(arrayTest, arrayTest.length);
This would allow the object to be defensive against malicious code trying to modify arrays after construction and validation by constructor. In fact most IDEs have analysis tools which will give you a warning against saving array reference.
add a comment |
In Java, objects/arrays are manipulated through reference variables#
When a function is invoked with arrays as their arguments, only a reference to the array is passed. Therefore, when you mutate array
array, the arrayTest
field also get mutated as they are referring to the same address
To override this behavior, you can create a copy of the array in your constructor using Object.clone()
method like:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone();
# Source: Wikipedia
add a comment |
As others have already pointed out: The array is passed as a reference to the Person
. So changes that are later done to the array will be visible to the Person
object. But that's only one half of the problem: You are not only passing a reference to the array to the constructor of the Person
, you are also returning a reference from the getArray
method.
Generally speaking, and as StephenC already pointed out in his answer: One important aspect of Object-Oriented design is to properly manage the state space of objects. It should not be possible for users of a class to bring an object into any form of "inconsistent state".
And this is difficult with plain primitive arrays. Consider the following pseudocode, referring to the class that you posted:
int originalArray[] = new int[2];
originalArray[0] = 12;
originalArray[1] = 34;
Person person = new Person(originalArray);
int arrayFromPerson[] = person.getArray();
originalArray[0] = -666; // Modify the original array
System.out.println(arrayFromPerson[0]) // Prints -666 - this is unexpected!
arrayFromPerson[1] = 12345678; // Modify the array from the person
System.out.println(originalArray[1]) // Prints 12345678 - this is unexpected!
Nobody knows who has a reference to the array, and nobody can verify or track that the contents of the array is not changed in any way. How critical this is becomes more obvious when you anticipate that the Person
object will be used at different places, possibly even by multiple threads.
Plain primitive arrays in Java do have their justification. But when they appear in the interface of a class (that is, in its public
methods), they should be view with scrutiny.
In order to be absolutely sure that nobody can interfere with the array that is stored in the Person
object, you'd have to create defensive copies everywhere:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int[] getArray()
return this.arrayTest.clone(); // Return a clone of the array
But this may be cumbersome. A more object-oriented solution could be to expose a "read-only view" on the state that is represented with the array. For example:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int getArrayLength()
return this.arrayTest.length;
public int getArrayElement(int index)
return this.arrayTest[index];
(Of course, in practice, you'd name the methods accordingly, depending on what the array actually represents. For example, if it's the ages of the children of the person, you'd call the methods getNumChildren()
and getAgeOfChild(int i)
or so...)
Another option how this can be solved is to expose an (unmodifiable) List
view on the array. This can, for example, be done with the asUnmodifiableList
method that is shown in this answer.
add a comment |
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55428172%2fhow-to-prevent-changing-the-value-of-variable%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
Array is passed by reference in Java. If you pass the original array to the constructor of Person
, you are passing the reference to the original array. So any change in arrayTest
inside Person
instance will reflect in original array(int[] array
) and vice-versa.
If you don't want to change the value of elements of original array in Person
instance then you have two options:
You can modify the code in
Person
constructor to create a copy of original array usingjava.util.Arrays.copyOf
method and then use that copy:public Person(int[] arrayTest)
this.arrayTest = java.util.Arrays.copyOf(arrayTest, arrayTest.length);Don't pass the original array to constructor, instead just send a copy of original array:
Person obj1 = new Person(java.util.Arrays.copyOf(array, array.length));
However, I would prefer first approach.
2
I agree with this answer. But from the two options stated here, First option should be the most suitable approach. The reason is, whenever you or someone else is going to use the code, they will not make the mistake mentioned in the question.
– LeoN
2 days ago
On the one hand, the first option is clearly better for the reason stated above, but the second option is useful too and should be considered. Doing what the OP accidentally did is useful in quite a few cases (although it violates some OOP principles, but I don't hold those in very high regard anyway)
– DreamConspiracy
2 days ago
add a comment |
Array is passed by reference in Java. If you pass the original array to the constructor of Person
, you are passing the reference to the original array. So any change in arrayTest
inside Person
instance will reflect in original array(int[] array
) and vice-versa.
If you don't want to change the value of elements of original array in Person
instance then you have two options:
You can modify the code in
Person
constructor to create a copy of original array usingjava.util.Arrays.copyOf
method and then use that copy:public Person(int[] arrayTest)
this.arrayTest = java.util.Arrays.copyOf(arrayTest, arrayTest.length);Don't pass the original array to constructor, instead just send a copy of original array:
Person obj1 = new Person(java.util.Arrays.copyOf(array, array.length));
However, I would prefer first approach.
2
I agree with this answer. But from the two options stated here, First option should be the most suitable approach. The reason is, whenever you or someone else is going to use the code, they will not make the mistake mentioned in the question.
– LeoN
2 days ago
On the one hand, the first option is clearly better for the reason stated above, but the second option is useful too and should be considered. Doing what the OP accidentally did is useful in quite a few cases (although it violates some OOP principles, but I don't hold those in very high regard anyway)
– DreamConspiracy
2 days ago
add a comment |
Array is passed by reference in Java. If you pass the original array to the constructor of Person
, you are passing the reference to the original array. So any change in arrayTest
inside Person
instance will reflect in original array(int[] array
) and vice-versa.
If you don't want to change the value of elements of original array in Person
instance then you have two options:
You can modify the code in
Person
constructor to create a copy of original array usingjava.util.Arrays.copyOf
method and then use that copy:public Person(int[] arrayTest)
this.arrayTest = java.util.Arrays.copyOf(arrayTest, arrayTest.length);Don't pass the original array to constructor, instead just send a copy of original array:
Person obj1 = new Person(java.util.Arrays.copyOf(array, array.length));
However, I would prefer first approach.
Array is passed by reference in Java. If you pass the original array to the constructor of Person
, you are passing the reference to the original array. So any change in arrayTest
inside Person
instance will reflect in original array(int[] array
) and vice-versa.
If you don't want to change the value of elements of original array in Person
instance then you have two options:
You can modify the code in
Person
constructor to create a copy of original array usingjava.util.Arrays.copyOf
method and then use that copy:public Person(int[] arrayTest)
this.arrayTest = java.util.Arrays.copyOf(arrayTest, arrayTest.length);Don't pass the original array to constructor, instead just send a copy of original array:
Person obj1 = new Person(java.util.Arrays.copyOf(array, array.length));
However, I would prefer first approach.
edited 2 days ago
answered 2 days ago
Aniket SahrawatAniket Sahrawat
6,44621340
6,44621340
2
I agree with this answer. But from the two options stated here, First option should be the most suitable approach. The reason is, whenever you or someone else is going to use the code, they will not make the mistake mentioned in the question.
– LeoN
2 days ago
On the one hand, the first option is clearly better for the reason stated above, but the second option is useful too and should be considered. Doing what the OP accidentally did is useful in quite a few cases (although it violates some OOP principles, but I don't hold those in very high regard anyway)
– DreamConspiracy
2 days ago
add a comment |
2
I agree with this answer. But from the two options stated here, First option should be the most suitable approach. The reason is, whenever you or someone else is going to use the code, they will not make the mistake mentioned in the question.
– LeoN
2 days ago
On the one hand, the first option is clearly better for the reason stated above, but the second option is useful too and should be considered. Doing what the OP accidentally did is useful in quite a few cases (although it violates some OOP principles, but I don't hold those in very high regard anyway)
– DreamConspiracy
2 days ago
2
2
I agree with this answer. But from the two options stated here, First option should be the most suitable approach. The reason is, whenever you or someone else is going to use the code, they will not make the mistake mentioned in the question.
– LeoN
2 days ago
I agree with this answer. But from the two options stated here, First option should be the most suitable approach. The reason is, whenever you or someone else is going to use the code, they will not make the mistake mentioned in the question.
– LeoN
2 days ago
On the one hand, the first option is clearly better for the reason stated above, but the second option is useful too and should be considered. Doing what the OP accidentally did is useful in quite a few cases (although it violates some OOP principles, but I don't hold those in very high regard anyway)
– DreamConspiracy
2 days ago
On the one hand, the first option is clearly better for the reason stated above, but the second option is useful too and should be considered. Doing what the OP accidentally did is useful in quite a few cases (although it violates some OOP principles, but I don't hold those in very high regard anyway)
– DreamConspiracy
2 days ago
add a comment |
There is no such thing as immutable (unchangeable) array in Java. The Java language does not support this, and neither does the JVM. You can't solve this at the language level.
In general, the only way to prevent changes to an array is to not share the reference to the array with other code that might change it.
In your example, you have what is known as a leaky abstraction. You are passing an array to your Person
class, and the caller is keeping a reference to that array so that it can change it. To solve this, you can:
- copy the array, and pass a reference to the copy, or
- have the constructor (or a setter for the array attribute) make the copy.
(See answer https://stackoverflow.com/a/55428214/139985 for example code.)
The second alternative is preferable from an OO perspective. The Person
class should be responsible for preserving its own internal state from interference ... if that is your design requirement. It should not rely on the caller to do this. (Even if the caller is technically part of the same class as is the case here.)
by the way, about Leaky abstraction, Joel on Software has a relevant blog article joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions
– Pac0
2 days ago
add a comment |
There is no such thing as immutable (unchangeable) array in Java. The Java language does not support this, and neither does the JVM. You can't solve this at the language level.
In general, the only way to prevent changes to an array is to not share the reference to the array with other code that might change it.
In your example, you have what is known as a leaky abstraction. You are passing an array to your Person
class, and the caller is keeping a reference to that array so that it can change it. To solve this, you can:
- copy the array, and pass a reference to the copy, or
- have the constructor (or a setter for the array attribute) make the copy.
(See answer https://stackoverflow.com/a/55428214/139985 for example code.)
The second alternative is preferable from an OO perspective. The Person
class should be responsible for preserving its own internal state from interference ... if that is your design requirement. It should not rely on the caller to do this. (Even if the caller is technically part of the same class as is the case here.)
by the way, about Leaky abstraction, Joel on Software has a relevant blog article joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions
– Pac0
2 days ago
add a comment |
There is no such thing as immutable (unchangeable) array in Java. The Java language does not support this, and neither does the JVM. You can't solve this at the language level.
In general, the only way to prevent changes to an array is to not share the reference to the array with other code that might change it.
In your example, you have what is known as a leaky abstraction. You are passing an array to your Person
class, and the caller is keeping a reference to that array so that it can change it. To solve this, you can:
- copy the array, and pass a reference to the copy, or
- have the constructor (or a setter for the array attribute) make the copy.
(See answer https://stackoverflow.com/a/55428214/139985 for example code.)
The second alternative is preferable from an OO perspective. The Person
class should be responsible for preserving its own internal state from interference ... if that is your design requirement. It should not rely on the caller to do this. (Even if the caller is technically part of the same class as is the case here.)
There is no such thing as immutable (unchangeable) array in Java. The Java language does not support this, and neither does the JVM. You can't solve this at the language level.
In general, the only way to prevent changes to an array is to not share the reference to the array with other code that might change it.
In your example, you have what is known as a leaky abstraction. You are passing an array to your Person
class, and the caller is keeping a reference to that array so that it can change it. To solve this, you can:
- copy the array, and pass a reference to the copy, or
- have the constructor (or a setter for the array attribute) make the copy.
(See answer https://stackoverflow.com/a/55428214/139985 for example code.)
The second alternative is preferable from an OO perspective. The Person
class should be responsible for preserving its own internal state from interference ... if that is your design requirement. It should not rely on the caller to do this. (Even if the caller is technically part of the same class as is the case here.)
edited 2 days ago
answered 2 days ago
Stephen CStephen C
525k72585944
525k72585944
by the way, about Leaky abstraction, Joel on Software has a relevant blog article joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions
– Pac0
2 days ago
add a comment |
by the way, about Leaky abstraction, Joel on Software has a relevant blog article joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions
– Pac0
2 days ago
by the way, about Leaky abstraction, Joel on Software has a relevant blog article joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions
– Pac0
2 days ago
by the way, about Leaky abstraction, Joel on Software has a relevant blog article joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions
– Pac0
2 days ago
add a comment |
There is no unmodifiable array, but you can make an unmodifiable list:
List<Integer> list = List.of(5, 10);
You will have to change your code to use lists instead of arrays, but this is generally preferable anyway.
If you already have an array of a non-primitive type, you can wrap it in an unmodifiable list, like so:
List<Integer> list = Collections.unmodifiableList(Arrays.asList(array));
However, while you can't change the list directly, changing the array will change the list. Moreover, this won't work on int[]
, but only on subclasses of Object[]
.
add a comment |
There is no unmodifiable array, but you can make an unmodifiable list:
List<Integer> list = List.of(5, 10);
You will have to change your code to use lists instead of arrays, but this is generally preferable anyway.
If you already have an array of a non-primitive type, you can wrap it in an unmodifiable list, like so:
List<Integer> list = Collections.unmodifiableList(Arrays.asList(array));
However, while you can't change the list directly, changing the array will change the list. Moreover, this won't work on int[]
, but only on subclasses of Object[]
.
add a comment |
There is no unmodifiable array, but you can make an unmodifiable list:
List<Integer> list = List.of(5, 10);
You will have to change your code to use lists instead of arrays, but this is generally preferable anyway.
If you already have an array of a non-primitive type, you can wrap it in an unmodifiable list, like so:
List<Integer> list = Collections.unmodifiableList(Arrays.asList(array));
However, while you can't change the list directly, changing the array will change the list. Moreover, this won't work on int[]
, but only on subclasses of Object[]
.
There is no unmodifiable array, but you can make an unmodifiable list:
List<Integer> list = List.of(5, 10);
You will have to change your code to use lists instead of arrays, but this is generally preferable anyway.
If you already have an array of a non-primitive type, you can wrap it in an unmodifiable list, like so:
List<Integer> list = Collections.unmodifiableList(Arrays.asList(array));
However, while you can't change the list directly, changing the array will change the list. Moreover, this won't work on int[]
, but only on subclasses of Object[]
.
edited 2 days ago
answered 2 days ago
Brian McCutchonBrian McCutchon
4,98222136
4,98222136
add a comment |
add a comment |
Instead of passing a copy of the array to the object, as others have suggested, I would recommend that the Person object's constructor should create a copy. Which means instead of,
this.arrayTest = arrayTest;
It should be
this.arrayTest = Arrays.copyOf(arrayTest, arrayTest.length);
This would allow the object to be defensive against malicious code trying to modify arrays after construction and validation by constructor. In fact most IDEs have analysis tools which will give you a warning against saving array reference.
add a comment |
Instead of passing a copy of the array to the object, as others have suggested, I would recommend that the Person object's constructor should create a copy. Which means instead of,
this.arrayTest = arrayTest;
It should be
this.arrayTest = Arrays.copyOf(arrayTest, arrayTest.length);
This would allow the object to be defensive against malicious code trying to modify arrays after construction and validation by constructor. In fact most IDEs have analysis tools which will give you a warning against saving array reference.
add a comment |
Instead of passing a copy of the array to the object, as others have suggested, I would recommend that the Person object's constructor should create a copy. Which means instead of,
this.arrayTest = arrayTest;
It should be
this.arrayTest = Arrays.copyOf(arrayTest, arrayTest.length);
This would allow the object to be defensive against malicious code trying to modify arrays after construction and validation by constructor. In fact most IDEs have analysis tools which will give you a warning against saving array reference.
Instead of passing a copy of the array to the object, as others have suggested, I would recommend that the Person object's constructor should create a copy. Which means instead of,
this.arrayTest = arrayTest;
It should be
this.arrayTest = Arrays.copyOf(arrayTest, arrayTest.length);
This would allow the object to be defensive against malicious code trying to modify arrays after construction and validation by constructor. In fact most IDEs have analysis tools which will give you a warning against saving array reference.
answered 2 days ago
Sourabh BhatSourabh Bhat
1,2601018
1,2601018
add a comment |
add a comment |
In Java, objects/arrays are manipulated through reference variables#
When a function is invoked with arrays as their arguments, only a reference to the array is passed. Therefore, when you mutate array
array, the arrayTest
field also get mutated as they are referring to the same address
To override this behavior, you can create a copy of the array in your constructor using Object.clone()
method like:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone();
# Source: Wikipedia
add a comment |
In Java, objects/arrays are manipulated through reference variables#
When a function is invoked with arrays as their arguments, only a reference to the array is passed. Therefore, when you mutate array
array, the arrayTest
field also get mutated as they are referring to the same address
To override this behavior, you can create a copy of the array in your constructor using Object.clone()
method like:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone();
# Source: Wikipedia
add a comment |
In Java, objects/arrays are manipulated through reference variables#
When a function is invoked with arrays as their arguments, only a reference to the array is passed. Therefore, when you mutate array
array, the arrayTest
field also get mutated as they are referring to the same address
To override this behavior, you can create a copy of the array in your constructor using Object.clone()
method like:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone();
# Source: Wikipedia
In Java, objects/arrays are manipulated through reference variables#
When a function is invoked with arrays as their arguments, only a reference to the array is passed. Therefore, when you mutate array
array, the arrayTest
field also get mutated as they are referring to the same address
To override this behavior, you can create a copy of the array in your constructor using Object.clone()
method like:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone();
# Source: Wikipedia
edited 2 days ago
answered 2 days ago
rv7rv7
2,2061425
2,2061425
add a comment |
add a comment |
As others have already pointed out: The array is passed as a reference to the Person
. So changes that are later done to the array will be visible to the Person
object. But that's only one half of the problem: You are not only passing a reference to the array to the constructor of the Person
, you are also returning a reference from the getArray
method.
Generally speaking, and as StephenC already pointed out in his answer: One important aspect of Object-Oriented design is to properly manage the state space of objects. It should not be possible for users of a class to bring an object into any form of "inconsistent state".
And this is difficult with plain primitive arrays. Consider the following pseudocode, referring to the class that you posted:
int originalArray[] = new int[2];
originalArray[0] = 12;
originalArray[1] = 34;
Person person = new Person(originalArray);
int arrayFromPerson[] = person.getArray();
originalArray[0] = -666; // Modify the original array
System.out.println(arrayFromPerson[0]) // Prints -666 - this is unexpected!
arrayFromPerson[1] = 12345678; // Modify the array from the person
System.out.println(originalArray[1]) // Prints 12345678 - this is unexpected!
Nobody knows who has a reference to the array, and nobody can verify or track that the contents of the array is not changed in any way. How critical this is becomes more obvious when you anticipate that the Person
object will be used at different places, possibly even by multiple threads.
Plain primitive arrays in Java do have their justification. But when they appear in the interface of a class (that is, in its public
methods), they should be view with scrutiny.
In order to be absolutely sure that nobody can interfere with the array that is stored in the Person
object, you'd have to create defensive copies everywhere:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int[] getArray()
return this.arrayTest.clone(); // Return a clone of the array
But this may be cumbersome. A more object-oriented solution could be to expose a "read-only view" on the state that is represented with the array. For example:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int getArrayLength()
return this.arrayTest.length;
public int getArrayElement(int index)
return this.arrayTest[index];
(Of course, in practice, you'd name the methods accordingly, depending on what the array actually represents. For example, if it's the ages of the children of the person, you'd call the methods getNumChildren()
and getAgeOfChild(int i)
or so...)
Another option how this can be solved is to expose an (unmodifiable) List
view on the array. This can, for example, be done with the asUnmodifiableList
method that is shown in this answer.
add a comment |
As others have already pointed out: The array is passed as a reference to the Person
. So changes that are later done to the array will be visible to the Person
object. But that's only one half of the problem: You are not only passing a reference to the array to the constructor of the Person
, you are also returning a reference from the getArray
method.
Generally speaking, and as StephenC already pointed out in his answer: One important aspect of Object-Oriented design is to properly manage the state space of objects. It should not be possible for users of a class to bring an object into any form of "inconsistent state".
And this is difficult with plain primitive arrays. Consider the following pseudocode, referring to the class that you posted:
int originalArray[] = new int[2];
originalArray[0] = 12;
originalArray[1] = 34;
Person person = new Person(originalArray);
int arrayFromPerson[] = person.getArray();
originalArray[0] = -666; // Modify the original array
System.out.println(arrayFromPerson[0]) // Prints -666 - this is unexpected!
arrayFromPerson[1] = 12345678; // Modify the array from the person
System.out.println(originalArray[1]) // Prints 12345678 - this is unexpected!
Nobody knows who has a reference to the array, and nobody can verify or track that the contents of the array is not changed in any way. How critical this is becomes more obvious when you anticipate that the Person
object will be used at different places, possibly even by multiple threads.
Plain primitive arrays in Java do have their justification. But when they appear in the interface of a class (that is, in its public
methods), they should be view with scrutiny.
In order to be absolutely sure that nobody can interfere with the array that is stored in the Person
object, you'd have to create defensive copies everywhere:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int[] getArray()
return this.arrayTest.clone(); // Return a clone of the array
But this may be cumbersome. A more object-oriented solution could be to expose a "read-only view" on the state that is represented with the array. For example:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int getArrayLength()
return this.arrayTest.length;
public int getArrayElement(int index)
return this.arrayTest[index];
(Of course, in practice, you'd name the methods accordingly, depending on what the array actually represents. For example, if it's the ages of the children of the person, you'd call the methods getNumChildren()
and getAgeOfChild(int i)
or so...)
Another option how this can be solved is to expose an (unmodifiable) List
view on the array. This can, for example, be done with the asUnmodifiableList
method that is shown in this answer.
add a comment |
As others have already pointed out: The array is passed as a reference to the Person
. So changes that are later done to the array will be visible to the Person
object. But that's only one half of the problem: You are not only passing a reference to the array to the constructor of the Person
, you are also returning a reference from the getArray
method.
Generally speaking, and as StephenC already pointed out in his answer: One important aspect of Object-Oriented design is to properly manage the state space of objects. It should not be possible for users of a class to bring an object into any form of "inconsistent state".
And this is difficult with plain primitive arrays. Consider the following pseudocode, referring to the class that you posted:
int originalArray[] = new int[2];
originalArray[0] = 12;
originalArray[1] = 34;
Person person = new Person(originalArray);
int arrayFromPerson[] = person.getArray();
originalArray[0] = -666; // Modify the original array
System.out.println(arrayFromPerson[0]) // Prints -666 - this is unexpected!
arrayFromPerson[1] = 12345678; // Modify the array from the person
System.out.println(originalArray[1]) // Prints 12345678 - this is unexpected!
Nobody knows who has a reference to the array, and nobody can verify or track that the contents of the array is not changed in any way. How critical this is becomes more obvious when you anticipate that the Person
object will be used at different places, possibly even by multiple threads.
Plain primitive arrays in Java do have their justification. But when they appear in the interface of a class (that is, in its public
methods), they should be view with scrutiny.
In order to be absolutely sure that nobody can interfere with the array that is stored in the Person
object, you'd have to create defensive copies everywhere:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int[] getArray()
return this.arrayTest.clone(); // Return a clone of the array
But this may be cumbersome. A more object-oriented solution could be to expose a "read-only view" on the state that is represented with the array. For example:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int getArrayLength()
return this.arrayTest.length;
public int getArrayElement(int index)
return this.arrayTest[index];
(Of course, in practice, you'd name the methods accordingly, depending on what the array actually represents. For example, if it's the ages of the children of the person, you'd call the methods getNumChildren()
and getAgeOfChild(int i)
or so...)
Another option how this can be solved is to expose an (unmodifiable) List
view on the array. This can, for example, be done with the asUnmodifiableList
method that is shown in this answer.
As others have already pointed out: The array is passed as a reference to the Person
. So changes that are later done to the array will be visible to the Person
object. But that's only one half of the problem: You are not only passing a reference to the array to the constructor of the Person
, you are also returning a reference from the getArray
method.
Generally speaking, and as StephenC already pointed out in his answer: One important aspect of Object-Oriented design is to properly manage the state space of objects. It should not be possible for users of a class to bring an object into any form of "inconsistent state".
And this is difficult with plain primitive arrays. Consider the following pseudocode, referring to the class that you posted:
int originalArray[] = new int[2];
originalArray[0] = 12;
originalArray[1] = 34;
Person person = new Person(originalArray);
int arrayFromPerson[] = person.getArray();
originalArray[0] = -666; // Modify the original array
System.out.println(arrayFromPerson[0]) // Prints -666 - this is unexpected!
arrayFromPerson[1] = 12345678; // Modify the array from the person
System.out.println(originalArray[1]) // Prints 12345678 - this is unexpected!
Nobody knows who has a reference to the array, and nobody can verify or track that the contents of the array is not changed in any way. How critical this is becomes more obvious when you anticipate that the Person
object will be used at different places, possibly even by multiple threads.
Plain primitive arrays in Java do have their justification. But when they appear in the interface of a class (that is, in its public
methods), they should be view with scrutiny.
In order to be absolutely sure that nobody can interfere with the array that is stored in the Person
object, you'd have to create defensive copies everywhere:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int[] getArray()
return this.arrayTest.clone(); // Return a clone of the array
But this may be cumbersome. A more object-oriented solution could be to expose a "read-only view" on the state that is represented with the array. For example:
public Person(int[] arrayTest)
this.arrayTest = arrayTest.clone(); // Store a clone of the array
public int getArrayLength()
return this.arrayTest.length;
public int getArrayElement(int index)
return this.arrayTest[index];
(Of course, in practice, you'd name the methods accordingly, depending on what the array actually represents. For example, if it's the ages of the children of the person, you'd call the methods getNumChildren()
and getAgeOfChild(int i)
or so...)
Another option how this can be solved is to expose an (unmodifiable) List
view on the array. This can, for example, be done with the asUnmodifiableList
method that is shown in this answer.
answered 2 days ago
Marco13Marco13
43k858111
43k858111
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55428172%2fhow-to-prevent-changing-the-value-of-variable%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown