开发者

Java Array Load from Attribute

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 class static: It doesn't need to access any fields from the containing class Test - 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜