Java可变数组长度

Java可变数组长度,java,arrays,variables,Java,Arrays,Variables,我在编译java项目时遇到问题,因为数组长度整数(它是一个变量)在我的对象数组中没有正确替换 import java.util.Arrays; public class ObjectList { private int N; private Object[] fractionList = new Object[N]; public ObjectList(int n){ this.N = n; } public int capacity

我在编译java项目时遇到问题,因为数组长度整数(它是一个变量)在我的对象数组中没有正确替换

import java.util.Arrays;

public class ObjectList {
    private int N;
    private Object[] fractionList = new Object[N];

    public ObjectList(int n){
        this.N = n;
    }

    public int capacity(){
        return this.N;
    }

    public void setN(int n){
    this.N = n;
    }

    public String toString(){
        return Arrays.toString(fractionList);
    }
}

public class FractionDriver {
    public static void main(String[] args){

    // creates the object list, sets N to 4
    ObjectList list = new ObjectList(4);

    System.out.println("The Objectlist has " + list.capacity() + " lines");

    // prints the array
    System.out.println(list.toString());
    }
}
这是编译器的输出:

The ObjectList has 4 lines
[]
因此,我无法向数组中添加任何对象。编译器抛出ArrayIndexOutOfBoundsException:0,并告诉我数组中没有元素

如果我选择替换对象数组实例变量中的N,如下所示:

private Object[] fractionList = new Object[4];
编译器很高兴,将数组长度设置为4


我做错了什么?

您可以在构造函数中创建数组实例,其中长度已知:

private Object[] fractionList;

public ObjectList(int n){
    this.N = n;
    this.fractionList = new Object[n];
}
但是,在更改N的值时,也可能需要重新创建数组:

public void setN(int n){
    this.N = n;
    // consider copying data from the old array to the new array
    this.fractionList = new Object[n];
}

问题是这条线

private Object[] fractionList = new Object[N];
在构造函数之前执行。初始化顺序始终如下所示:

  • 如果有超类-首先初始化它
  • 静态变量声明和静态初始值设定项的出现顺序
  • 实例变量声明和实例初始值设定项的出现顺序
  • 构造器
  • 您希望构造函数(4)中的代码设置数组长度,但该数组已在实例变量(3)中创建

    我建议如下:

    public class ObjectList {
        private int N;
        private Object[] fractionList;
    
        public ObjectList(int n){
            fractionList = new Object[n];
            this.N = n;
        }
    
        public int capacity(){
            return this.N;
        }
    
        public void setN(int n){
            // might want to copy content from old array to new one here
            fractionList = new Object[n];
            this.N = n;
        }
    
        public String toString(){
            return Arrays.toString(fractionList);
        }
    }
    

    如果您想遵守JavaBeans,我还建议首先将
    capacity()
    方法重命名为
    getCapacity()

    ,这不是编译错误。程序编译得很好。问题是数组
    fractionList
    在调用构造函数主体之前就被初始化了,在该主体中设置了变量
    N

    您可以将初始化移动到构造函数:

    private Object[] fractionList;
    
    
    public ObjectList(int n) {
        this.N = n;
        fractionList = new Object[N];
    }
    

    嗯。。。简单地说,当
    对象[]分形列表
    初始化时,字段
    N
    的值是“不可见的”,因为它的值在
    这之前不会被设置。N=N被调用,这与文本数字4不同,后者是编译时常量

    您可以将参数
    N
    传递给构造函数以初始化数组。比如:

    public ObjectList(int n){
        this.fractionList = new Object[n];
    }
    

    消息不是来自编译器。这是您的程序的输出。如果您仍然需要帮助,请不要忘记将答案标记为已接受,或者在答案的注释中要求澄清,@nisoramen。在setN方法中,我们不仅应该重新创建,而且还应该处理将现有元素克隆到新数组中的问题,但这只是一个小小的改进:)@Beri yes,我在代码中的注释中提到了这一点。但这取决于setN所需的逻辑。当然,您还应该处理新数组太小而无法容纳旧数组元素的情况。