I'm trying to override Variables that are already defined.
Here is my code:
package com.diesal11;
import java.lang.reflect.Array;
public class Test{
private class List {
public String[] words;
public List(String[] array) {
this.words = array;
}
}
public List[] all;
public Test() {
this.all = new List[2];
String[] array = new String[2];
array[0] = "One";
array[1] = "Two";
this.all[0] = new List(array);
array[0] = "Three";
array[1] = "Four";
this.all[1] = new List(array);
System.out.println(this.all[开发者_如何转开发0].words[0]);
System.out.println(this.all[0].words[1]);
System.out.println(this.all[1].words[0]);
System.out.println(this.all[1].words[1]);
}
public static void main(String[] args) {
Test test = new Test();
}
}
The problem is the console prints out:
Three
Four
Three
Four
How can I fix this? the actual code I need this for is setup in this way so it can't change much.
Thanks in advance!
The problem is you are storing a reference to the array passed to the List constructor.
You then change that same array and pass it to the 2nd List object.
Instead, create a new array and pass that in like this:
...
String[] array = new String[2];
array[0] = "One";
array[1] = "Two";
this.all[0] = new List(array);
array = new String[2]; // CREATE A NEW ARRAY
array[0] = "Three";
array[1] = "Four";
this.all[1] = new List(array);
...
EDITED - Added style-related feedback
Your bigger problem is this code has lots of style issues:
- Don't call you class
List
: You should avoid using class names from the JDK, especially from the Collections framework - Make your
MyList
classstatic
: It doesn't need to access any fields from the containing classTest
- it's a DTO - From a design point of view, your code has highlighted the problem with keeping references to mutable objects - you have no control over what the calling code does to your object (in this case, as array).
A simple change that avoids this problem would be this:
static MyList {
String[] words;
public MyList(String... words) {
this.words = words;
}
}
...
this.all[0] = new List("one", "two");
The syntax String... words
is called a "varargs" parameter - it creates an array on the fly that only the method has a reference to (although arrays can also be passed in, giving you the same problem).
The only safe way is to make a copy of the array and store that, or provide a method that allows you to add a word (using a List to hold the words for example)
- In general, try to avoid arrays - prefer using Collections
You need to pass in a new array for the second element in this.all
.
String[] array = new String[2];
array[0] = "One";
array[1] = "Two";
this.all[0] = new List(array);
array = new String[2];
array[0] = "Three";
array[1] = "Four";
this.all[1] = new List(array);
The variable array
points to the same memory each time you pass it into the List
constructor.
You should create new String[] for the second instance; by re-using the first array
you are merely changing the elements in the same array which all[0]
and all[1]
both refer to. In other words, all[0]
and all[1]
refer to the same location in memory.
String[] array = new String[2];
array[0] = "One";
array[1] = "Two";
this.all[0] = new List(array);
String[] array = new String[2];
array[0] = "Three";
array[1] = "Four";
this.all[1] = new List(array);
or to save lines of code:
this.all[0] = new List(new String[] {"One", "Two"});
this.all[1] = new List(new String[] {"Two", "Three"});
Also it is a bad practice to name one of your classes the same as a common data type (java.util.List
). This will lead to confusion down the line.
精彩评论