Java可変配列長

私のJavaプロジェクトをコンパイルするのに問題があります。これは、配列の長さ整数(これは変数です)が私のObject配列で正しく代用されていないためです。

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に設定します。

何がおかしいのですか?

2
メッセージはコンパイラから来たものではありません。これはあなたのプログラムの出力です。
追加された 著者 Joshua,
メッセージはコンパイラから来たものではありません。これはあなたのプログラムの出力です。
追加された 著者 Joshua,
あなたがまだ助けを必要としているのであれば、答えを承認済みとしてマークするか、答えのコメントに明確化を求めることを忘れないでください。@nisoramen。
追加された 著者 Mathias Bader,
あなたがまだ助けを必要としているのであれば、答えを承認済みとしてマークするか、答えのコメントに明確化を求めることを忘れないでください。@nisoramen。
追加された 著者 Mathias Bader,

8 答え

あなたは、長さがすでにわかっているあなたのコンストラクタの中に配列インスタンスを作ることができます:

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];
}
4
追加された
@ベリーはい、私はコード内のコメントでそれを述べた。それはsetNの必要なロジックにもよりますが。もちろん、新しい配列が小さすぎて古い配列の要素に収まらない場合も処理する必要があります。
追加された 著者 Eran,
setNメソッドでは、作成し直すだけでなく、既存の要素を新しいArrayに複製することも処理できますが、それは小さな改善点にすぎません:)
追加された 著者 Beri,

あなたは、長さがすでにわかっているあなたのコンストラクタの中に配列インスタンスを作ることができます:

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];
}
4
追加された
@ベリーはい、私はコード内のコメントでそれを述べた。それはsetNの必要なロジックにもよりますが。もちろん、新しい配列が小さすぎて古い配列の要素に収まらない場合も処理する必要があります。
追加された 著者 Eran,
setNメソッドでは、作成し直すだけでなく、既存の要素を新しいArrayに複製することも処理できますが、それは小さな改善点にすぎません:)
追加された 著者 Beri,

問題はその線です

private Object[] fractionList = new Object[N];

あなたのコンストラクタの前に実行されます。初期化の順序は常に次のとおりです。

  1. スーパークラスがある場合 - 最初に初期化してください
  2. 出現順の静的変数宣言と静的初期化子
  3. 出現順にインスタンス変数の宣言とインスタンスの初期化子
  4. コンストラクタです。

コンストラクタ(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);
    }
}

Java Beansに準拠したい場合は、 capacity()メソッドを getCapacity()に名前変更することをお勧めします。

2
追加された

問題はその線です

private Object[] fractionList = new Object[N];

あなたのコンストラクタの前に実行されます。初期化の順序は常に次のとおりです。

  1. スーパークラスがある場合 - 最初に初期化してください
  2. 出現順の静的変数宣言と静的初期化子
  3. 出現順にインスタンス変数の宣言とインスタンスの初期化子
  4. コンストラクタです。

コンストラクタ(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);
    }
}

Java Beansに準拠したい場合は、 capacity()メソッドを getCapacity()に名前変更することをお勧めします。

2
追加された

まずこれはコンパイルエラーではありません。プログラムは正常にコンパイルされています。問題は、変数 N が設定されている場所で、コンストラクタの本体が呼び出される前に 配列 fractionList が初期化されることです。

初期化をコンストラクタに移動できます。

private Object[] fractionList;


public ObjectList(int n) {
    this.N = n;
    fractionList = new Object[N];
}
1
追加された

まずこれはコンパイルエラーではありません。プログラムは正常にコンパイルされています。問題は、変数 N が設定されている場所で、コンストラクタの本体が呼び出される前に 配列 fractionList が初期化されることです。

初期化をコンストラクタに移動できます。

private Object[] fractionList;


public ObjectList(int n) {
    this.N = n;
    fractionList = new Object[N];
}
1
追加された

簡単に言うと、 Object [] fractionList が初期化されると、 N フィールドの値は<�非表示>になります。 code> this.N = n; が呼び出されます。これは、コンパイル時に定数であるリテラル番号4とは異なります。

配列を初期化するためにコンストラクタにパラメータ N を渡すことができます。何かのようなもの:

public ObjectList(int n){
    this.fractionList = new Object[n];
}
0
追加された

簡単に言うと、 Object [] fractionList が初期化されると、 N フィールドの値は<�非表示>になります。 code> this.N = n; が呼び出されます。これは、コンパイル時に定数であるリテラル番号4とは異なります。

配列を初期化するためにコンストラクタにパラメータ N を渡すことができます。何かのようなもの:

public ObjectList(int n){
    this.fractionList = new Object[n];
}
0
追加された